<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-10457042</id><updated>2012-01-01T20:16:46.750+01:00</updated><title type='text'>Nicola's MAME Ramblings</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://mamelife.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://mamelife.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Nicola Salmoria</name><uri>http://www.blogger.com/profile/06048642443376701628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>63</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-10457042.post-117171582069777064</id><published>2007-02-17T13:06:00.000+01:00</published><updated>2007-02-17T13:39:12.363+01:00</updated><title type='text'>CPS2 not much left to do</title><content type='html'>When I originally wrote the key searching program, that was on the assumption that the key for the second Feistel network was 96 bits long.&lt;br /&gt;&lt;br /&gt;Each (E,D) pair reduces the key space by a factor of about 2&lt;sup&gt;16&lt;/sup&gt;, so to isolate the correct key with good confidence one would need at least 96/16 = 6 (E,D) pairs.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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).&lt;br /&gt;&lt;br /&gt;The end result is a program that is orders of magnitude faster than the previous one.&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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).&lt;br /&gt;&lt;br /&gt;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&lt;sup&gt;48&lt;/sup&gt;, therefore leaving about 2&lt;sup&gt;16&lt;/sup&gt; 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.&lt;br /&gt;&lt;br /&gt;In the meantime, Andreas Naive has been busy implementing the attack he had &lt;a href="http://andreasnaive.blogspot.com/2007/02/cps-2-11.html"&gt;described on his blog&lt;/a&gt;, 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.&lt;br /&gt;&lt;br /&gt;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.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10457042-117171582069777064?l=mamelife.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mamelife.blogspot.com/feeds/117171582069777064/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10457042&amp;postID=117171582069777064' title='55 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/117171582069777064'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/117171582069777064'/><link rel='alternate' type='text/html' href='http://mamelife.blogspot.com/2007/02/cps2-not-much-left-to-do.html' title='CPS2 not much left to do'/><author><name>Nicola Salmoria</name><uri>http://www.blogger.com/profile/06048642443376701628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>55</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10457042.post-116937754701213882</id><published>2007-01-21T12:05:00.000+01:00</published><updated>2007-02-17T11:33:16.476+01:00</updated><title type='text'>CPS2 Key Bit Order</title><content type='html'>As &lt;a href="http://mamelife.blogspot.com/2007/01/cps2-getting-closer.html"&gt;previously mentioned&lt;/a&gt;, the 64-bit keys I'm currently using should be the same as the hardware ones, except for a fixed permutation of the bits.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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):&lt;br /&gt;&lt;br /&gt;3D9E1E15A58C32CE&lt;br /&gt;3599DF35AD98284C&lt;br /&gt;B74433502F4653D7&lt;br /&gt;8758E3923FFA1A50&lt;br /&gt;F0AE3D08420DD6BF&lt;br /&gt;6260014FD857F7A7&lt;br /&gt;&lt;br /&gt;there is something immediately obvious about those keys: they all contain exactly 32 0s and 32 1s.&lt;br /&gt;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 &lt;em&gt;million&lt;/em&gt;! So we can be pretty sure that those keys are &lt;strong&gt;not&lt;/strong&gt; random numbers.&lt;br /&gt;&lt;br /&gt;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:&lt;br /&gt;&lt;br /&gt;0123456789ABCDEF&lt;br /&gt;1032547698BADCFE&lt;br /&gt;45673210CDEFAB89&lt;br /&gt;67451032FEDC98BA&lt;br /&gt;89ABDCEF45672301&lt;br /&gt;CDEFBA9823016754&lt;br /&gt;&lt;br /&gt;looks much better doesn't it?&lt;br /&gt;Though there's no way to tell how close it is to the real thing.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10457042-116937754701213882?l=mamelife.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mamelife.blogspot.com/feeds/116937754701213882/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10457042&amp;postID=116937754701213882' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/116937754701213882'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/116937754701213882'/><link rel='alternate' type='text/html' href='http://mamelife.blogspot.com/2007/01/cps2-key-bit-order.html' title='CPS2 Key Bit Order'/><author><name>Nicola Salmoria</name><uri>http://www.blogger.com/profile/06048642443376701628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10457042.post-116924264481953261</id><published>2007-01-19T22:37:00.000+01:00</published><updated>2007-01-21T11:46:55.323+01:00</updated><title type='text'>CPS2 Moving Slowly Now</title><content type='html'>The &lt;a href="http://mamelife.blogspot.com/2007/01/cps2-fight-continues.html"&gt;improved attack&lt;/a&gt; works, and I've been able to recover a few more keys, but it takes a lot of computation time--several hours per game.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;One of the new versions supported is mshb, which I is the first Brazilian version of a CPS2 game to work.&lt;br /&gt;&lt;br /&gt;Andreas has published details on a theoretical &lt;a href="http://andreasnaive.blogspot.com/2007/01/cps-2-10.html"&gt;attack&lt;/a&gt; using &lt;a href="http://en.wikipedia.org/wiki/Linear_cryptanalysis"&gt;differential cryptanalysis&lt;/a&gt; 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&lt;sup&gt;16&lt;/sup&gt;-2&lt;sup&gt;17&lt;/sup&gt;, which is a bit steep, but we should be able to do that in a few cases.&lt;br /&gt;&lt;br /&gt;One thing to note about &lt;a href="http://mamelife.blogspot.com/2007/01/how-to-bruteforce-cps2.html"&gt;my attack&lt;/a&gt;, 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.&lt;br /&gt;&lt;br /&gt;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.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10457042-116924264481953261?l=mamelife.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mamelife.blogspot.com/feeds/116924264481953261/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10457042&amp;postID=116924264481953261' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/116924264481953261'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/116924264481953261'/><link rel='alternate' type='text/html' href='http://mamelife.blogspot.com/2007/01/cps2-moving-slowly-now.html' title='CPS2 Moving Slowly Now'/><author><name>Nicola Salmoria</name><uri>http://www.blogger.com/profile/06048642443376701628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10457042.post-116907500474529968</id><published>2007-01-17T23:38:00.000+01:00</published><updated>2007-01-19T22:13:25.836+01:00</updated><title type='text'>CPS2 The Fight Continues</title><content type='html'>I've finished going through all the games previously supported by MAME using XOR files, and generating keys using &lt;a href="http://mamelife.blogspot.com/2007/01/how-to-bruteforce-cps2.html"&gt;this attack&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;Most of the games provided at least 8 pairs, a few 7, so the attack worked.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;The others provide 4 pairs, and I'm now trying to still perform the attack, using a new trick.&lt;br /&gt;&lt;br /&gt;Remember the &lt;a href="http://mamelife.blogspot.com/2006/12/cps2-notes-part-2.html"&gt;complementation property&lt;/a&gt;? For every address A, we know that exists another address A&lt;sub&gt;1&lt;/sub&gt; such that D(X, A) = D(X ^ 0xffff, A&lt;sub&gt;1&lt;/sub&gt;) ^ 0xffff. The problem is that we don't know A&lt;sub&gt;1&lt;/sub&gt;. 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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10457042-116907500474529968?l=mamelife.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mamelife.blogspot.com/feeds/116907500474529968/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10457042&amp;postID=116907500474529968' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/116907500474529968'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/116907500474529968'/><link rel='alternate' type='text/html' href='http://mamelife.blogspot.com/2007/01/cps2-fight-continues.html' title='CPS2 The Fight Continues'/><author><name>Nicola Salmoria</name><uri>http://www.blogger.com/profile/06048642443376701628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10457042.post-116880139841169559</id><published>2007-01-14T19:37:00.000+01:00</published><updated>2007-01-17T23:38:07.630+01:00</updated><title type='text'>CPS2 Getting Closer</title><content type='html'>The 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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;The result is here: http://xoomer.alice.it/nicola.salmoria/cps2crptv2.zip.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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.&lt;pre&gt;pzloop2:  3332206a0077f829&lt;br /&gt;mshj:     01c0c951370f4c80&lt;br /&gt;dstlka:   04048b4e2a498879&lt;br /&gt;ringdest: 0405541367806575&lt;br /&gt;cybotsj:  0404821534388354&lt;/pre&gt;&lt;br /&gt;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.&lt;br /&gt;Some of the watchdog values contain birth dates, e.g. cmpi.l  #$19660419,D1, so I expect the same thing might be happening here.&lt;br /&gt;Also, it makes sense for the pzloop2 one to be more regular than the others because it's third party game.&lt;br /&gt;&lt;br /&gt;On the key extraction front, things are going reasonably well. The brute force attack described in the &lt;a href="http://mamelife.blogspot.com/2007/01/how-to-bruteforce-cps2.html"&gt;previous article&lt;/a&gt; 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.&lt;br /&gt;&lt;br /&gt;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.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10457042-116880139841169559?l=mamelife.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mamelife.blogspot.com/feeds/116880139841169559/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10457042&amp;postID=116880139841169559' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/116880139841169559'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/116880139841169559'/><link rel='alternate' type='text/html' href='http://mamelife.blogspot.com/2007/01/cps2-getting-closer.html' title='CPS2 Getting Closer'/><author><name>Nicola Salmoria</name><uri>http://www.blogger.com/profile/06048642443376701628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10457042.post-116862699228972073</id><published>2007-01-12T19:36:00.000+01:00</published><updated>2007-01-14T19:37:32.766+01:00</updated><title type='text'>How to bruteforce CPS2</title><content type='html'>I 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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;So the idea I had is to use a meet in the middle brute force attack which exploits a weakness in the s-boxes.&lt;br /&gt;&lt;br /&gt;Remember that&lt;br /&gt;&lt;br /&gt;L&lt;sub&gt;1&lt;/sub&gt; = R&lt;sub&gt;0&lt;/sub&gt;&lt;br /&gt;R&lt;sub&gt;1&lt;/sub&gt; = L&lt;sub&gt;0&lt;/sub&gt; XOR f&lt;sub&gt;1&lt;/sub&gt;(R&lt;sub&gt;0&lt;/sub&gt;)&lt;br /&gt;&lt;br /&gt;L&lt;sub&gt;2&lt;/sub&gt; = R&lt;sub&gt;1&lt;/sub&gt;&lt;br /&gt;R&lt;sub&gt;2&lt;/sub&gt; = L&lt;sub&gt;1&lt;/sub&gt; XOR f&lt;sub&gt;2&lt;/sub&gt;(R&lt;sub&gt;1&lt;/sub&gt;)&lt;br /&gt;&lt;br /&gt;L&lt;sub&gt;3&lt;/sub&gt; = R&lt;sub&gt;2&lt;/sub&gt;&lt;br /&gt;R&lt;sub&gt;3&lt;/sub&gt; = L&lt;sub&gt;2&lt;/sub&gt; XOR f&lt;sub&gt;3&lt;/sub&gt;(R&lt;sub&gt;2&lt;/sub&gt;)&lt;br /&gt;&lt;br /&gt;L&lt;sub&gt;4&lt;/sub&gt; = R&lt;sub&gt;3&lt;/sub&gt;&lt;br /&gt;R&lt;sub&gt;4&lt;/sub&gt; = L&lt;sub&gt;3&lt;/sub&gt; XOR f&lt;sub&gt;4&lt;/sub&gt;(R&lt;sub&gt;3&lt;/sub&gt;)&lt;br /&gt;&lt;br /&gt;Remember also that the f&lt;sub&gt;n&lt;/sub&gt; round functions are made of 4 s-boxes each.&lt;br /&gt;These are the 16 s-boxes, with their inputs and outputs:&lt;br /&gt;&lt;pre&gt;f1b1  03457- 67&lt;br /&gt;f1b2  12346- 35&lt;br /&gt;f1b3  124567 14&lt;br /&gt;f1b4  023567 02&lt;br /&gt;&lt;br /&gt;f2b1  0246-- 46&lt;br /&gt;f2b2  134567 03&lt;br /&gt;f2b3  013457 17&lt;br /&gt;f2b4  123567 25&lt;br /&gt;&lt;br /&gt;f3b1  2346-- 35&lt;br /&gt;f3b2  01357- 02&lt;br /&gt;f3b3  012357 16&lt;br /&gt;f3b4  024567 47&lt;br /&gt;&lt;br /&gt;f4b1  01367- 03&lt;br /&gt;f4b2  012456 47&lt;br /&gt;f4b3  023457 12&lt;br /&gt;f4b4  234567 56&lt;/pre&gt;&lt;br /&gt;f2b1 is the weakest link. It has only four inputs, 0246. To get those four inputs, we need just &lt;em&gt;three&lt;/em&gt; 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.&lt;br /&gt;&lt;br /&gt;So if we start from the ciphertext and run it through the first two rounds of the Feistel network, scanning all 2&lt;sup&gt;24&lt;/sup&gt; possible keys for f1b1, f1b3, f1b4, and f2b1, we'll get all possible values for bits 46 of R2.&lt;br /&gt;&lt;br /&gt;Now let's start from the plaintext instead, and go up. If we scan all 2&lt;sup&gt;6&lt;/sup&gt; keys for f4b2, we'll get all possible values for bits 47 of R2 again.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;Should we consider ourselves finished after that?&lt;br /&gt;&lt;br /&gt;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.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10457042-116862699228972073?l=mamelife.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mamelife.blogspot.com/feeds/116862699228972073/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10457042&amp;postID=116862699228972073' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/116862699228972073'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/116862699228972073'/><link rel='alternate' type='text/html' href='http://mamelife.blogspot.com/2007/01/how-to-bruteforce-cps2.html' title='How to bruteforce CPS2'/><author><name>Nicola Salmoria</name><uri>http://www.blogger.com/profile/06048642443376701628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10457042.post-116838266619495855</id><published>2007-01-09T23:26:00.000+01:00</published><updated>2007-01-12T19:37:03.343+01:00</updated><title type='text'>CPS2 coming to MAME</title><content type='html'>I've submitted to MAMEDEV the code to replace the 4GB CHDs with 192-bit keys.&lt;br /&gt;The code is here: http://xoomer.alice.it/nicola.salmoria/cps2crpt.zip&lt;br /&gt;It contains all the information needed to understand the algorithm, including the s-boxes.&lt;br /&gt;&lt;br /&gt;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).&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10457042-116838266619495855?l=mamelife.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mamelife.blogspot.com/feeds/116838266619495855/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10457042&amp;postID=116838266619495855' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/116838266619495855'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/116838266619495855'/><link rel='alternate' type='text/html' href='http://mamelife.blogspot.com/2007/01/cps2-coming-to-mame.html' title='CPS2 coming to MAME'/><author><name>Nicola Salmoria</name><uri>http://www.blogger.com/profile/06048642443376701628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10457042.post-116822211657288301</id><published>2007-01-08T02:16:00.000+01:00</published><updated>2007-01-09T23:25:51.646+01:00</updated><title type='text'>CPS2 Fundamental Breakthrough</title><content type='html'>Today 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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;So the algorithm turns out to be like this:&lt;ol&gt;&lt;br /&gt;&lt;li&gt;Take the 16-bit address and a 96-bit key and run them through the first Feistel network, to produce a 16-bit subkey.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;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&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;Once that is done, producing keys for games that we have complete tables for will be quite simple.&lt;br /&gt;&lt;br /&gt;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 &lt;a href="http://en.wikipedia.org/wiki/Differential_cryptanalysis"&gt;differential cryptanalysis&lt;/a&gt; techniques we'd need.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10457042-116822211657288301?l=mamelife.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mamelife.blogspot.com/feeds/116822211657288301/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10457042&amp;postID=116822211657288301' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/116822211657288301'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/116822211657288301'/><link rel='alternate' type='text/html' href='http://mamelife.blogspot.com/2007/01/cps2-fundamental-breakthrough.html' title='CPS2 Fundamental Breakthrough'/><author><name>Nicola Salmoria</name><uri>http://www.blogger.com/profile/06048642443376701628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10457042.post-116813734850466536</id><published>2007-01-07T02:16:00.000+01:00</published><updated>2007-01-08T01:51:54.146+01:00</updated><title type='text'>CPS2 Won't Be Tamed That Easily</title><content type='html'>Some people thought we were almost finished with the CPS2 algorithm, but this doesn't seem to be the case.&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;From the full tables, we can extract a 96-bit subkey for every address.&lt;br /&gt;&lt;em&gt;Edit: I had a link to a file here. I've removed it since I've found an error which I'll correct soon.&lt;/em&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;The problem now is to understand how the hardware generates the 96-bit subkey starting from the address and from the global key.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;We can generate only &lt;em&gt;94&lt;/em&gt; 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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;The scheme should be as follows:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;take 16-bit address, N-bit global key, and generate a 16-bit key seed using an unknown algorithm.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;take 16-bit key seed, M-bit global key, and generate 96-bit subkey using an unknown algorithm.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;take 16-bit ciphertext, 96-bit subkey, and generate 16-bit plaintext using the algorithm we have discovered.&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;I think it would make sense for the algorithm in step 1. to be another 4-round Feistel network.&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;Let's see that with an example. Let's say that the first algorithm generates a 4-bit key seed, &lt;em&gt;abcd&lt;/em&gt;, which is expanded into the 6-bit subkey &lt;em&gt;ABCDEF&lt;/em&gt; this way:&lt;br /&gt;&lt;br /&gt;A = a&lt;br /&gt;B = a XOR b&lt;br /&gt;C = a XOR c&lt;br /&gt;D = b XOR c&lt;br /&gt;E = b XOR d&lt;br /&gt;F = b XOR c XOR d&lt;br /&gt;&lt;br /&gt;We don't know anything about &lt;em&gt;abcd&lt;/em&gt;, all we see is &lt;em&gt;ABCDEF&lt;/em&gt;, but we need to guess what &lt;em&gt;abcd&lt;/em&gt; looks like. So we notice that&lt;br /&gt;&lt;br /&gt;D = B XOR C&lt;br /&gt;F = A XOR C XOR E&lt;br /&gt;&lt;br /&gt;and we decide that&lt;br /&gt;&lt;br /&gt;a' = A&lt;br /&gt;b' = B&lt;br /&gt;c' = C&lt;br /&gt;d' = E&lt;br /&gt;&lt;br /&gt;so we would have&lt;br /&gt;&lt;br /&gt;A = a'&lt;br /&gt;B = b'&lt;br /&gt;C = c'&lt;br /&gt;D = b' XOR c'&lt;br /&gt;E = d'&lt;br /&gt;F = a' XOR c' XOR d'&lt;br /&gt;&lt;br /&gt;This all works as far as generating the subkey from the seed goes, the problem is that &lt;em&gt;abcd&lt;/em&gt; and &lt;em&gt;a'b'c'd'&lt;/em&gt; are two completely different numbers! We have that&lt;br /&gt;&lt;br /&gt;&lt;em&gt;a'b'c'd'&lt;/em&gt; = &lt;em&gt;abcd&lt;/em&gt; XOR &lt;em&gt;aab&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;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.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10457042-116813734850466536?l=mamelife.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mamelife.blogspot.com/feeds/116813734850466536/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10457042&amp;postID=116813734850466536' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/116813734850466536'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/116813734850466536'/><link rel='alternate' type='text/html' href='http://mamelife.blogspot.com/2007/01/cps2-wont-be-tamed-that-easily.html' title='CPS2 Won&apos;t Be Tamed That Easily'/><author><name>Nicola Salmoria</name><uri>http://www.blogger.com/profile/06048642443376701628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10457042.post-116809206164431983</id><published>2007-01-06T14:47:00.000+01:00</published><updated>2007-01-07T03:41:09.533+01:00</updated><title type='text'>CPS2 Subkeys</title><content type='html'>I 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.&lt;br /&gt;&lt;br /&gt;A subkey consists of 24*4 = 96 bits. There are 65536 subkeys, so the total is 786kB of data.&lt;br /&gt;&lt;br /&gt;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).&lt;br /&gt;&lt;br /&gt;So this hints at a 64-bit global key, while the independent subkey bits drop for now at 96-1-59 = 36 bits.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10457042-116809206164431983?l=mamelife.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mamelife.blogspot.com/feeds/116809206164431983/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10457042&amp;postID=116809206164431983' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/116809206164431983'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/116809206164431983'/><link rel='alternate' type='text/html' href='http://mamelife.blogspot.com/2007/01/cps2-subkeys.html' title='CPS2 Subkeys'/><author><name>Nicola Salmoria</name><uri>http://www.blogger.com/profile/06048642443376701628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10457042.post-116800098342948369</id><published>2007-01-05T13:42:00.000+01:00</published><updated>2007-01-07T03:40:51.606+01:00</updated><title type='text'>CPS2 S-Boxes ready</title><content type='html'>Andy has published his program but is reporting some &lt;a href="http://andreasnaive.blogspot.com/2007/01/cps-2-9.html"&gt;problems&lt;/a&gt; in recreating the original tables--the values generated by his program are XORed with a constant value when compared with the original table.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;Let's recap how this was done. The fundamental idea was published by &lt;a href="http://andreasnaive.blogspot.com/2006/12/cps-2-5.html"&gt;Andy&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;since R&lt;sub&gt;4&lt;/sub&gt; = L&lt;sub&gt;3&lt;/sub&gt; XOR F&lt;sub&gt;4&lt;/sub&gt;(L&lt;sub&gt;4&lt;/sub&gt;), if you pick (E,D) and (E',D') such that L&lt;sub&gt;4&lt;/sub&gt; = L'&lt;sub&gt;4&lt;/sub&gt;, then&lt;br /&gt;&lt;br /&gt;R'&lt;sub&gt;4&lt;/sub&gt; = L'&lt;sub&gt;3&lt;/sub&gt; XOR F&lt;sub&gt;4&lt;/sub&gt;(L'&lt;sub&gt;4&lt;/sub&gt;) = L'&lt;sub&gt;3&lt;/sub&gt; XOR F&lt;sub&gt;4&lt;/sub&gt;(L&lt;sub&gt;4&lt;/sub&gt;) = L'&lt;sub&gt;3&lt;/sub&gt; XOR R&lt;sub&gt;4&lt;/sub&gt; XOR L&lt;sub&gt;3&lt;/sub&gt;&lt;br /&gt;&lt;br /&gt;therefore&lt;br /&gt;&lt;br /&gt;L&lt;sub&gt;3&lt;/sub&gt; XOR L'&lt;sub&gt;3&lt;/sub&gt; = R&lt;sub&gt;4&lt;/sub&gt; XOR R'&lt;sub&gt;4&lt;/sub&gt;&lt;br /&gt;&lt;br /&gt;Now if we pick (E,D) and (E',D') such that L&lt;sub&gt;4&lt;/sub&gt; = L'&lt;sub&gt;4&lt;/sub&gt; 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.&lt;br /&gt;&lt;br /&gt;That knowledge can easily be used to determine F&lt;sub&gt;4&lt;/sub&gt;. Take (E,D) and (E',D'), where E and E' differ only by one bit which we know doesn't affect bit &lt;em&gt;b&lt;/em&gt; in L&lt;sub&gt;3&lt;/sub&gt;. Then we know that&lt;br /&gt;&lt;br /&gt;B&lt;sub&gt;b&lt;/sub&gt;(L&lt;sub&gt;3&lt;/sub&gt; XOR L'&lt;sub&gt;3&lt;/sub&gt;) = 0&lt;br /&gt;&lt;br /&gt;where B&lt;sub&gt;b&lt;/sub&gt;(x) gives me the value of bit b of x.&lt;br /&gt;&lt;br /&gt;Therefore&lt;br /&gt;&lt;br /&gt;B&lt;sub&gt;b&lt;/sub&gt;(R&lt;sub&gt;4&lt;/sub&gt; XOR F&lt;sub&gt;4&lt;/sub&gt;(L&lt;sub&gt;4&lt;/sub&gt;) XOR R'&lt;sub&gt;4&lt;/sub&gt; XOR F&lt;sub&gt;4&lt;/sub&gt;(L'&lt;sub&gt;4&lt;/sub&gt;)) = 0&lt;br /&gt;&lt;br /&gt;that is,&lt;br /&gt;&lt;br /&gt;B&lt;sub&gt;b&lt;/sub&gt;(F&lt;sub&gt;4&lt;/sub&gt;(L&lt;sub&gt;4&lt;/sub&gt;) XOR F&lt;sub&gt;4&lt;/sub&gt;(L'&lt;sub&gt;4&lt;/sub&gt;)) = B&lt;sub&gt;b&lt;/sub&gt;(R&lt;sub&gt;4&lt;/sub&gt; XOR R'&lt;sub&gt;4&lt;/sub&gt;)&lt;br /&gt;&lt;br /&gt;Do that for all &lt;em&gt;b&lt;/em&gt; and for all E, E' pairs, and you quickly reconstruct the whole F&lt;sub&gt;4&lt;/sub&gt; structure. I'm saying its structure and not F&lt;sub&gt;4&lt;/sub&gt; itself, because it's all done through XOR so you need to set F&lt;sub&gt;4&lt;/sub&gt;(0) arbitrarily, then all the others are derived from it through XOR.&lt;br /&gt;&lt;br /&gt;After F&lt;sub&gt;4&lt;/sub&gt; is reconstructed, it can be used to undo the fourth round of the encryption. Then you repeat exactly the same process to reconstruct F&lt;sub&gt;3&lt;/sub&gt; (still XOR an arbitrary value). Then use F&lt;sub&gt;3&lt;/sub&gt; to undo the third round, and you are left with just two rounds.&lt;br /&gt;&lt;br /&gt;Now things get really simple, because by definition&lt;br /&gt;&lt;br /&gt;L&lt;sub&gt;2&lt;/sub&gt; = L&lt;sub&gt;0&lt;/sub&gt; XOR F&lt;sub&gt;1&lt;/sub&gt;(R&lt;sub&gt;0&lt;/sub&gt;)&lt;br /&gt;R&lt;sub&gt;2&lt;/sub&gt; = R&lt;sub&gt;0&lt;/sub&gt; XOR F&lt;sub&gt;2&lt;/sub&gt;(L&lt;sub&gt;2&lt;/sub&gt;)&lt;br /&gt;&lt;br /&gt;and since you know all of L&lt;sub&gt;0&lt;/sub&gt;, R&lt;sub&gt;0&lt;/sub&gt;, L&lt;sub&gt;2&lt;/sub&gt;, and R&lt;sub&gt;2&lt;/sub&gt;, F&lt;sub&gt;1&lt;/sub&gt; and F&lt;sub&gt;2&lt;/sub&gt; are immediately derived as&lt;br /&gt;&lt;br /&gt;F&lt;sub&gt;1&lt;/sub&gt;(R&lt;sub&gt;0&lt;/sub&gt;) = L&lt;sub&gt;0&lt;/sub&gt; XOR L&lt;sub&gt;2&lt;/sub&gt;&lt;br /&gt;F&lt;sub&gt;2&lt;/sub&gt;(L&lt;sub&gt;2&lt;/sub&gt;) = R&lt;sub&gt;0&lt;/sub&gt; XOR R&lt;sub&gt;2&lt;/sub&gt;&lt;br /&gt;&lt;br /&gt;Note that here we derive F&lt;sub&gt;1&lt;/sub&gt; and F&lt;sub&gt;2&lt;/sub&gt; explicitly, not XOR an arbitrary value.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10457042-116800098342948369?l=mamelife.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mamelife.blogspot.com/feeds/116800098342948369/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10457042&amp;postID=116800098342948369' title='13 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/116800098342948369'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/116800098342948369'/><link rel='alternate' type='text/html' href='http://mamelife.blogspot.com/2007/01/cps2-s-boxes-ready.html' title='CPS2 S-Boxes ready'/><author><name>Nicola Salmoria</name><uri>http://www.blogger.com/profile/06048642443376701628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>13</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10457042.post-116785802223252975</id><published>2007-01-03T22:00:00.000+01:00</published><updated>2007-01-04T12:55:04.356+01:00</updated><title type='text'>CPS2 is not a 4-round Feistel network (...NOT)</title><content type='html'>&lt;em&gt;Edit: As Andy pointed out, the following reasoning is fatally flawed by the fact that the f&lt;sub&gt;n&lt;/sub&gt; functions are &lt;strong&gt;not&lt;/strong&gt; bijective.&lt;br /&gt;&lt;br /&gt;So, given the strong evidence Andy has found, it really looks like the algorithm is a 4-round Feistel network.&lt;br /&gt;&lt;br /&gt;This is actually good news, I have to say I am relieved ;)&lt;br /&gt;&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;Remember that&lt;br /&gt;&lt;br /&gt;L&lt;sub&gt;1&lt;/sub&gt; = R&lt;sub&gt;0&lt;/sub&gt;&lt;br /&gt;R&lt;sub&gt;1&lt;/sub&gt; = L&lt;sub&gt;0&lt;/sub&gt; XOR f&lt;sub&gt;1&lt;/sub&gt;(R&lt;sub&gt;0&lt;/sub&gt;)&lt;br /&gt;&lt;br /&gt;L&lt;sub&gt;2&lt;/sub&gt; = R&lt;sub&gt;1&lt;/sub&gt;&lt;br /&gt;R&lt;sub&gt;2&lt;/sub&gt; = L&lt;sub&gt;1&lt;/sub&gt; XOR f&lt;sub&gt;2&lt;/sub&gt;(R&lt;sub&gt;1&lt;/sub&gt;)&lt;br /&gt;&lt;br /&gt;L&lt;sub&gt;3&lt;/sub&gt; = R&lt;sub&gt;2&lt;/sub&gt;&lt;br /&gt;R&lt;sub&gt;3&lt;/sub&gt; = L&lt;sub&gt;2&lt;/sub&gt; XOR f&lt;sub&gt;3&lt;/sub&gt;(R&lt;sub&gt;2&lt;/sub&gt;)&lt;br /&gt;&lt;br /&gt;L&lt;sub&gt;4&lt;/sub&gt; = R&lt;sub&gt;3&lt;/sub&gt;&lt;br /&gt;R&lt;sub&gt;4&lt;/sub&gt; = L&lt;sub&gt;3&lt;/sub&gt; XOR f&lt;sub&gt;4&lt;/sub&gt;(R&lt;sub&gt;3&lt;/sub&gt;)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;In the &lt;a href="http://mamelife.blogspot.com/2007/01/cps2-is-not-4-round-feistel-network.html"&gt;previous article&lt;/a&gt; I showed that if we take (E,D) and (E',D') such that L&lt;sub&gt;0&lt;/sub&gt; XOR L&lt;sub&gt;4&lt;/sub&gt; = L'&lt;sub&gt;0&lt;/sub&gt; XOR L'&lt;sub&gt;4&lt;/sub&gt; and R&lt;sub&gt;0&lt;/sub&gt; = R'&lt;sub&gt;0&lt;/sub&gt;, then&lt;br /&gt;&lt;br /&gt;R&lt;sub&gt;2&lt;/sub&gt; = R'&lt;sub&gt;2&lt;/sub&gt;.&lt;br /&gt;&lt;br /&gt;I'll now take a different route from the one I took yesterday, to avoid the flaw that Andy noticed.&lt;br /&gt;&lt;br /&gt;From R&lt;sub&gt;2&lt;/sub&gt; = R'&lt;sub&gt;2&lt;/sub&gt; follows that&lt;br /&gt;&lt;br /&gt;L&lt;sub&gt;1&lt;/sub&gt; XOR f&lt;sub&gt;2&lt;/sub&gt;(R&lt;sub&gt;1&lt;/sub&gt;) = L'&lt;sub&gt;1&lt;/sub&gt; XOR f&lt;sub&gt;2&lt;/sub&gt;(R'&lt;sub&gt;1&lt;/sub&gt;), that is&lt;br /&gt;&lt;br /&gt;R&lt;sub&gt;0&lt;/sub&gt; XOR f&lt;sub&gt;2&lt;/sub&gt;(R&lt;sub&gt;1&lt;/sub&gt;) = R'&lt;sub&gt;0&lt;/sub&gt; XOR f&lt;sub&gt;2&lt;/sub&gt;(R'&lt;sub&gt;1&lt;/sub&gt;), that is (since R&lt;sub&gt;0&lt;/sub&gt; = R'&lt;sub&gt;0&lt;/sub&gt;)&lt;br /&gt;&lt;br /&gt;f&lt;sub&gt;2&lt;/sub&gt;(R&lt;sub&gt;1&lt;/sub&gt;) = f&lt;sub&gt;2&lt;/sub&gt;(R'&lt;sub&gt;1&lt;/sub&gt;), that is (since f2 is bijective)&lt;br /&gt;&lt;br /&gt;R&lt;sub&gt;1&lt;/sub&gt; = R'&lt;sub&gt;1&lt;/sub&gt;, that is&lt;br /&gt;&lt;br /&gt;L&lt;sub&gt;0&lt;/sub&gt; XOR f&lt;sub&gt;1&lt;/sub&gt;(R&lt;sub&gt;0&lt;/sub&gt;) = L'&lt;sub&gt;0&lt;/sub&gt; XOR f&lt;sub&gt;1&lt;/sub&gt;(R'&lt;sub&gt;0&lt;/sub&gt;), that is (since R&lt;sub&gt;0&lt;/sub&gt; = R'&lt;sub&gt;0&lt;/sub&gt;)&lt;br /&gt;&lt;br /&gt;L&lt;sub&gt;0&lt;/sub&gt; = L'&lt;sub&gt;0&lt;/sub&gt;, therefore&lt;br /&gt;&lt;br /&gt;(E,D) = (E',D')&lt;br /&gt;&lt;br /&gt;Therefore two different pairs with the requested property cannot exist.&lt;br /&gt;&lt;br /&gt;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&lt;sub&gt;4&lt;/sub&gt; in the above; we are only using L&lt;sub&gt;0&lt;/sub&gt;, R&lt;sub&gt;0&lt;/sub&gt;, and L&lt;sub&gt;4&lt;/sub&gt;. Also, we don't care about the effects of the permutation on L&lt;sub&gt;0&lt;/sub&gt; and R&lt;sub&gt;0&lt;/sub&gt;, the only thing we care about is that when we do L&lt;sub&gt;0&lt;/sub&gt; XOR L&lt;sub&gt;4&lt;/sub&gt; we XOR the correct bits together. So we can arbitrarily fix the permutation on L&lt;sub&gt;0&lt;/sub&gt; and R&lt;sub&gt;0&lt;/sub&gt;, and try all possible permutations on L&lt;sub&gt;4&lt;/sub&gt;.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;This doesn't happen: for every permutation, such pairs exist. Therefore CPS2 is not just a 4-round Feistel network.&lt;br /&gt;&lt;br /&gt;This is not to say that Andy isn't on the right track, on the contrary, the findings in &lt;a href="http://andreasnaive.blogspot.com/"&gt;CPS-2 (5)&lt;/a&gt; are extremely interesting, but the algorithm cannot be just a 4-round Feistel network. There's something else we are missing.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10457042-116785802223252975?l=mamelife.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mamelife.blogspot.com/feeds/116785802223252975/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10457042&amp;postID=116785802223252975' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/116785802223252975'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/116785802223252975'/><link rel='alternate' type='text/html' href='http://mamelife.blogspot.com/2007/01/cps2-is-not-4-round-feistel-network_03.html' title='CPS2 is not a 4-round Feistel network (...NOT)'/><author><name>Nicola Salmoria</name><uri>http://www.blogger.com/profile/06048642443376701628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10457042.post-116778131567234062</id><published>2007-01-02T23:41:00.000+01:00</published><updated>2007-01-04T12:54:49.686+01:00</updated><title type='text'>CPS2 is not a 4-round Feistel network (maybe)</title><content type='html'>&lt;em&gt;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.&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://andreasnaive.blogspot.com/"&gt;Andreas Naive&lt;/a&gt; has been doing some very interesting observations lately.&lt;br /&gt;&lt;br /&gt;I thought it would make sense to check if we were lucky and the algorithm was indeed structured like a 4-round &lt;a href="http://en.wikipedia.org/wiki/Feistel_cipher"&gt;Feistel network&lt;/a&gt; as Andy supposed.&lt;br /&gt;&lt;br /&gt;The basic idea of a Feistel network if that you have a &lt;em&gt;round function&lt;/em&gt; 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.&lt;br /&gt;&lt;br /&gt;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&lt;sub&gt;n&lt;/sub&gt; is used, where f&lt;sub&gt;n&lt;/sub&gt; describes a &lt;a href="http://en.wikipedia.org/wiki/Permutation"&gt;permutation&lt;/a&gt; of the values 0 to 255.&lt;br /&gt;&lt;br /&gt;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:&lt;br /&gt;L = { 0, 1, 2, 4, 6, 7, 13, 14 }&lt;br /&gt;R = { 3, 5, 8, 9, 10, 11, 12, 15 }&lt;br /&gt;&lt;br /&gt;So a 4-round Feistel network would work like this:&lt;br /&gt;Given the ciphertext E = (L&lt;sub&gt;0&lt;/sub&gt;, R&lt;sub&gt;0&lt;/sub&gt;),&lt;br /&gt;&lt;br /&gt;L&lt;sub&gt;1&lt;/sub&gt; = R&lt;sub&gt;0&lt;/sub&gt;&lt;br /&gt;R&lt;sub&gt;1&lt;/sub&gt; = L&lt;sub&gt;0&lt;/sub&gt; XOR f&lt;sub&gt;1&lt;/sub&gt;(R&lt;sub&gt;0&lt;/sub&gt;)&lt;br /&gt;&lt;br /&gt;L&lt;sub&gt;2&lt;/sub&gt; = R&lt;sub&gt;1&lt;/sub&gt;&lt;br /&gt;R&lt;sub&gt;2&lt;/sub&gt; = L&lt;sub&gt;1&lt;/sub&gt; XOR f&lt;sub&gt;2&lt;/sub&gt;(R&lt;sub&gt;1&lt;/sub&gt;)&lt;br /&gt;&lt;br /&gt;L&lt;sub&gt;3&lt;/sub&gt; = R&lt;sub&gt;2&lt;/sub&gt;&lt;br /&gt;R&lt;sub&gt;3&lt;/sub&gt; = L&lt;sub&gt;2&lt;/sub&gt; XOR f&lt;sub&gt;3&lt;/sub&gt;(R&lt;sub&gt;2&lt;/sub&gt;)&lt;br /&gt;&lt;br /&gt;L&lt;sub&gt;4&lt;/sub&gt; = R&lt;sub&gt;3&lt;/sub&gt;&lt;br /&gt;R&lt;sub&gt;4&lt;/sub&gt; = L&lt;sub&gt;3&lt;/sub&gt; XOR f&lt;sub&gt;4&lt;/sub&gt;(R&lt;sub&gt;3&lt;/sub&gt;)&lt;br /&gt;&lt;br /&gt;and the resulting plaintext is D = (L&lt;sub&gt;4&lt;/sub&gt;, R&lt;sub&gt;4&lt;/sub&gt;)&lt;br /&gt;&lt;br /&gt;By the properties of a Feistel network, we can also go backwards, starting from D = (L&lt;sub&gt;4&lt;/sub&gt;, R&lt;sub&gt;4&lt;/sub&gt;)&lt;br /&gt;&lt;br /&gt;R&lt;sub&gt;3&lt;/sub&gt; = L&lt;sub&gt;4&lt;/sub&gt;&lt;br /&gt;L&lt;sub&gt;3&lt;/sub&gt; = R&lt;sub&gt;4&lt;/sub&gt; XOR f&lt;sub&gt;4&lt;/sub&gt;(L&lt;sub&gt;4&lt;/sub&gt;)&lt;br /&gt;&lt;br /&gt;R&lt;sub&gt;2&lt;/sub&gt; = L&lt;sub&gt;3&lt;/sub&gt;&lt;br /&gt;L&lt;sub&gt;2&lt;/sub&gt; = R&lt;sub&gt;3&lt;/sub&gt; XOR f&lt;sub&gt;3&lt;/sub&gt;(L&lt;sub&gt;3&lt;/sub&gt;)&lt;br /&gt;&lt;br /&gt;R&lt;sub&gt;1&lt;/sub&gt; = L&lt;sub&gt;2&lt;/sub&gt;&lt;br /&gt;L&lt;sub&gt;1&lt;/sub&gt; = R&lt;sub&gt;2&lt;/sub&gt; XOR f&lt;sub&gt;2&lt;/sub&gt;(L&lt;sub&gt;2&lt;/sub&gt;)&lt;br /&gt;&lt;br /&gt;R&lt;sub&gt;0&lt;/sub&gt; = L&lt;sub&gt;1&lt;/sub&gt;&lt;br /&gt;L&lt;sub&gt;0&lt;/sub&gt; = R&lt;sub&gt;1&lt;/sub&gt; XOR f&lt;sub&gt;1&lt;/sub&gt;(L&lt;sub&gt;1&lt;/sub&gt;)&lt;br /&gt;&lt;br /&gt;Now let's start from both sides and meet in the middle. Going from E to D we have&lt;br /&gt;&lt;br /&gt;L&lt;sub&gt;2&lt;/sub&gt; = R&lt;sub&gt;1&lt;/sub&gt; = L&lt;sub&gt;0&lt;/sub&gt; XOR f&lt;sub&gt;1&lt;/sub&gt;(R&lt;sub&gt;0&lt;/sub&gt;)&lt;br /&gt;&lt;br /&gt;Going from D to E we have&lt;br /&gt;&lt;br /&gt;L&lt;sub&gt;2&lt;/sub&gt; = R&lt;sub&gt;3&lt;/sub&gt; XOR f&lt;sub&gt;3&lt;/sub&gt;(L&lt;sub&gt;3&lt;/sub&gt;) = L&lt;sub&gt;4&lt;/sub&gt; XOR f&lt;sub&gt;3&lt;/sub&gt;(R&lt;sub&gt;2&lt;/sub&gt;)&lt;br /&gt;&lt;br /&gt;Putting the two together we have&lt;br /&gt;&lt;br /&gt;L&lt;sub&gt;0&lt;/sub&gt; XOR f&lt;sub&gt;1&lt;/sub&gt;(R&lt;sub&gt;0&lt;/sub&gt;) = L&lt;sub&gt;4&lt;/sub&gt; XOR f&lt;sub&gt;3&lt;/sub&gt;(R&lt;sub&gt;2&lt;/sub&gt;), that is&lt;br /&gt;&lt;br /&gt;L&lt;sub&gt;0&lt;/sub&gt; XOR L&lt;sub&gt;4&lt;/sub&gt; = f&lt;sub&gt;1&lt;/sub&gt;(R&lt;sub&gt;0&lt;/sub&gt;) XOR f&lt;sub&gt;3&lt;/sub&gt;(R&lt;sub&gt;2&lt;/sub&gt;)&lt;br /&gt;&lt;br /&gt;Now remember that we know &lt;strong&gt;all&lt;/strong&gt; (E,D) pairs, so we can take advantage of that.&lt;br /&gt;If we take (E,D) and (E',D') such that L&lt;sub&gt;0&lt;/sub&gt; XOR L&lt;sub&gt;4&lt;/sub&gt; = L'&lt;sub&gt;0&lt;/sub&gt; XOR L'&lt;sub&gt;4&lt;/sub&gt;, then it follows that&lt;br /&gt;&lt;br /&gt;f&lt;sub&gt;1&lt;/sub&gt;(R&lt;sub&gt;0&lt;/sub&gt;) XOR f&lt;sub&gt;3&lt;/sub&gt;(R&lt;sub&gt;2&lt;/sub&gt;) = f&lt;sub&gt;1&lt;/sub&gt;(R'&lt;sub&gt;0&lt;/sub&gt;) XOR f&lt;sub&gt;3&lt;/sub&gt;(R'&lt;sub&gt;2&lt;/sub&gt;)&lt;br /&gt;&lt;br /&gt;If additionally E and E' are such that R&lt;sub&gt;0&lt;/sub&gt; = R'&lt;sub&gt;0&lt;/sub&gt;, then we are left with just&lt;br /&gt;&lt;br /&gt;f&lt;sub&gt;3&lt;/sub&gt;(R&lt;sub&gt;2&lt;/sub&gt;) = f&lt;sub&gt;3&lt;/sub&gt;(R'&lt;sub&gt;2&lt;/sub&gt;)&lt;br /&gt;&lt;br /&gt;and since f&lt;sub&gt;3&lt;/sub&gt; is a &lt;a href="http://en.wikipedia.org/wiki/Bijection"&gt;bijective function&lt;/a&gt;, this implies that&lt;br /&gt;&lt;br /&gt;R&lt;sub&gt;2&lt;/sub&gt; = R'&lt;sub&gt;2&lt;/sub&gt;, that is&lt;br /&gt;&lt;br /&gt;L&lt;sub&gt;3&lt;/sub&gt; = L'&lt;sub&gt;3&lt;/sub&gt;, that is&lt;br /&gt;&lt;br /&gt;R&lt;sub&gt;4&lt;/sub&gt; XOR f&lt;sub&gt;4&lt;/sub&gt;(L&lt;sub&gt;4&lt;/sub&gt;) = R'&lt;sub&gt;4&lt;/sub&gt; XOR f&lt;sub&gt;4&lt;/sub&gt;(L'&lt;sub&gt;4&lt;/sub&gt;), that is&lt;br /&gt;&lt;br /&gt;f&lt;sub&gt;4&lt;/sub&gt;(L&lt;sub&gt;4&lt;/sub&gt;) XOR f&lt;sub&gt;4&lt;/sub&gt;(L'&lt;sub&gt;4&lt;/sub&gt;) = R&lt;sub&gt;4&lt;/sub&gt; XOR R'&lt;sub&gt;4&lt;/sub&gt;&lt;br /&gt;&lt;br /&gt;Now we can repeat the procedure for all (E,D) pairs, and get a large number of equations on f&lt;sub&gt;4&lt;/sub&gt;.&lt;br /&gt;&lt;br /&gt;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&lt;sub&gt;4&lt;/sub&gt;.&lt;br /&gt;&lt;br /&gt;Unfortunately, they &lt;strong&gt;are&lt;/strong&gt; contradictory. E.g. you get something like this:&lt;br /&gt;&lt;br /&gt;f&lt;sub&gt;4&lt;/sub&gt;(0xff) XOR f&lt;sub&gt;4&lt;/sub&gt;(0xfc) = 0x11&lt;br /&gt;f&lt;sub&gt;4&lt;/sub&gt;(0xff) XOR f&lt;sub&gt;4&lt;/sub&gt;(0xfc) = 0x48&lt;br /&gt;&lt;br /&gt;Therefore CPS2 is not a 4-round Feistel network.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10457042-116778131567234062?l=mamelife.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mamelife.blogspot.com/feeds/116778131567234062/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10457042&amp;postID=116778131567234062' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/116778131567234062'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/116778131567234062'/><link rel='alternate' type='text/html' href='http://mamelife.blogspot.com/2007/01/cps2-is-not-4-round-feistel-network.html' title='CPS2 is not a 4-round Feistel network (maybe)'/><author><name>Nicola Salmoria</name><uri>http://www.blogger.com/profile/06048642443376701628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10457042.post-116655695812987638</id><published>2006-12-19T19:07:00.000+01:00</published><updated>2007-01-03T14:42:09.336+01:00</updated><title type='text'>CPS2 notes, part 5</title><content type='html'>In &lt;a href="http://mamelife.blogspot.com/2006/12/cps2-notes-part-1.html"&gt;part 1&lt;/a&gt; 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.&lt;br /&gt;But there's more than that. It seems that there are more properties which are true for all games, regardless of the key.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;      0    1    2    3    4    5    6    7&lt;br /&gt; 0 7FE0 75B0 8028 7AF4 6EB0 8284 734C 7420&lt;br /&gt; 1 8208 7FE0 7E48 7FA4 81CC 8050 72F8 7FDC&lt;br /&gt; 2 7F38 7F8C 8000 7FD0 87B0 7EF4 7BF8 8068&lt;br /&gt; 3 &lt;span style="background-color:red; color:white"&gt;7200&lt;/span&gt; &lt;span style="background-color:lime; color:black"&gt;6CA0&lt;/span&gt; &lt;span style="background-color:orange; color:white"&gt;7B00&lt;/span&gt; 76E0 &lt;span style="background-color:limegreen; color:white"&gt;6800&lt;/span&gt; 8044 &lt;span style="background-color:orange; color:white"&gt;B280&lt;/span&gt; &lt;span style="background-color:lime; color:black"&gt;8180&lt;/span&gt;&lt;br /&gt; 4 7F18 7FCC 7F84 8130 7BC4 80E4 8154 8014&lt;br /&gt; 5 8980 7B80 7780 81D4 6200 7D78 7540 7DE0&lt;br /&gt; 6 83C0 7E98 7F3C 831C 6CF0 8080 7BD8 7D20&lt;br /&gt; 7 80B0 81B0 7EAC 8190 7DB4 8050 8364 7F68&lt;br /&gt; 8 7D80 80E0 7D80 8110 78C0 7FC4 6F40 8DA0&lt;br /&gt; 9 &lt;span style="background-color:red; color:white"&gt;5080&lt;/span&gt; &lt;span style="background-color:green; color:white"&gt;7510&lt;/span&gt; &lt;span style="background-color:orange; color:white"&gt;C000&lt;/span&gt; 643C &lt;span style="background-color:palegreen; color:black"&gt;6DC0&lt;/span&gt; 8414 &lt;span style="background-color:orange; color:white"&gt;4800&lt;/span&gt; &lt;span style="background-color:green; color:white"&gt;72C0&lt;/span&gt;&lt;br /&gt;10 7BE0 7A30 7F40 7F08 6A00 8110 7720 7B80&lt;br /&gt;11 8040 81A0 7E80 7E2C 5680 7FFC 73C0 8020&lt;br /&gt;12 7A80 8370 7100 818C 7E80 7BE8 6200 8060&lt;br /&gt;13 8018 7D24 8040 7F60 7E2C 80EC 7F9C 7EA0&lt;br /&gt;14 7D18 7F00 7EEC 80DC 799C 7F90 7F34 8010&lt;br /&gt;15 7E80 8710 8540 8128 8200 7F50 7C40 8540&lt;br /&gt;&lt;br /&gt;      8    9   10   11   12   13   14   15&lt;br /&gt; 0 8054 7C58 7BF4 7E88 7C80 7610 7C7C 7C28&lt;br /&gt; 1 8008 7FA4 80F0 8020 7FB8 7E24 7EE8 8078&lt;br /&gt; 2 7FB8 7F18 7FE4 7F14 7FDC 80C0 7C3C 8130&lt;br /&gt; 3 80DC 7F34 7EE0 8124 77F0 &lt;span style="background-color:limegreen; color:white"&gt;7800&lt;/span&gt; &lt;span style="background-color:red; color:white"&gt;5A80&lt;/span&gt; 7064&lt;br /&gt; 4 800C 7F98 7D3C 7E60 803C 7C74 80E0 80A0&lt;br /&gt; 5 8024 7BA8 79C8 8020 7A24 7E00 7F60 7AAC&lt;br /&gt; 6 7F80 7E94 7B08 7FE8 7E98 6DA0 7FD4 7E50&lt;br /&gt; 7 7FE8 7E20 7D6C 7F88 8004 7BD4 803C 7FCC&lt;br /&gt; 8 7F4C 7FE4 7E48 7F10 7F40 7FC0 74C0 82B4&lt;br /&gt; 9 812C 8064 6520 78D8 7D5C &lt;span style="background-color:palegreen; color:black"&gt;5040&lt;/span&gt; &lt;span style="background-color:red; color:white"&gt;5800&lt;/span&gt; 8588&lt;br /&gt;10 7D50 7FB8 883C 7E00 7EDC 8A00 78E0 7FDC&lt;br /&gt;11 7EF8 7F64 7860 7E30 804C 6780 82C0 81E8&lt;br /&gt;12 8094 7CCC 7A44 7EF0 7FC0 7C80 8100 7EF4&lt;br /&gt;13 8180 7FA0 7FF4 8084 8000 8088 7F9C 8024&lt;br /&gt;14 8004 8080 809C 7F44 806C 8044 7A5C 7FEC&lt;br /&gt;15 7EC0 814C 7A10 7F2C 7E80 9200 7E20 8064&lt;/pre&gt;&lt;br /&gt;&lt;span style="background-color:red"&gt;&amp;nbsp&amp;nbsp&amp;nbsp&lt;/span&gt; are constant.&lt;br /&gt;&lt;br /&gt;&lt;span style="background-color:orange"&gt;&amp;nbsp&amp;nbsp&amp;nbsp&lt;/span&gt; are correlated and can be only one of 2 quadruplets.&lt;br /&gt;&lt;br /&gt;&lt;span style="background-color:lime"&gt;&amp;nbsp&amp;nbsp&amp;nbsp&lt;/span&gt; &lt;span style="background-color:limegreen"&gt;&amp;nbsp&amp;nbsp&amp;nbsp&lt;/span&gt; &lt;span style="background-color:palegreen"&gt;&amp;nbsp&amp;nbsp&amp;nbsp&lt;/span&gt; &lt;span style="background-color:green"&gt;&amp;nbsp&amp;nbsp&amp;nbsp&lt;/span&gt; are all correlated and values can be taken in one of 4 "groups".&lt;br /&gt;&lt;br /&gt;Once chosen the group:&lt;br /&gt;&lt;span style="background-color:lime"&gt;&amp;nbsp&amp;nbsp&amp;nbsp&lt;/span&gt; are correlated and can be only one of 2 pairs.&lt;br /&gt;&lt;span style="background-color:green"&gt;&amp;nbsp&amp;nbsp&amp;nbsp&lt;/span&gt; are correlated and can be only one of 2 pairs.&lt;br /&gt;&lt;span style="background-color:limegreen"&gt;&amp;nbsp&amp;nbsp&amp;nbsp&lt;/span&gt; are correlated and can be only one of 4 pairs.&lt;br /&gt;&lt;span style="background-color:palegreen"&gt;&amp;nbsp&amp;nbsp&amp;nbsp&lt;/span&gt; are fixed by &lt;span style="background-color:green"&gt;&amp;nbsp&amp;nbsp&amp;nbsp&lt;/span&gt; and &lt;span style="background-color:limegreen"&gt;&amp;nbsp&amp;nbsp&amp;nbsp&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;So in total there are 2x4x2x2x4 = 128 combinations. Each combination is used by exactly 256 tables.&lt;br /&gt;&lt;br /&gt;Note the symmetry of it all. 16 values are affected, related to 2 bits of the ciphertext and 8 bits of the plaintext.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10457042-116655695812987638?l=mamelife.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mamelife.blogspot.com/feeds/116655695812987638/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10457042&amp;postID=116655695812987638' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/116655695812987638'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/116655695812987638'/><link rel='alternate' type='text/html' href='http://mamelife.blogspot.com/2006/12/cps2-notes-part-5.html' title='CPS2 notes, part 5'/><author><name>Nicola Salmoria</name><uri>http://www.blogger.com/profile/06048642443376701628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10457042.post-116652430708111359</id><published>2006-12-19T11:17:00.000+01:00</published><updated>2007-01-02T23:39:40.853+01:00</updated><title type='text'>CPS2 notes, part 4</title><content type='html'>I 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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10457042-116652430708111359?l=mamelife.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mamelife.blogspot.com/feeds/116652430708111359/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10457042&amp;postID=116652430708111359' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/116652430708111359'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/116652430708111359'/><link rel='alternate' type='text/html' href='http://mamelife.blogspot.com/2006/12/cps2-notes-part-4.html' title='CPS2 notes, part 4'/><author><name>Nicola Salmoria</name><uri>http://www.blogger.com/profile/06048642443376701628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10457042.post-116647921308918460</id><published>2006-12-18T22:34:00.000+01:00</published><updated>2007-01-02T23:39:45.886+01:00</updated><title type='text'>CPS2 notes, part 3</title><content type='html'>In &lt;a href="http://mamelife.blogspot.com/2006/12/cps2-notes-part-1.html"&gt;part 1&lt;/a&gt; we were flipping bits in the ciphertext, and seeing what happened to bits in the plaintext.&lt;br /&gt;&lt;br /&gt;We can do the opposite, of course, and there's something unexpected in the results.&lt;br /&gt;I'll show the total number of times the bits change (in hex) instead of percentages, to make the point more visible.&lt;br /&gt;&lt;pre&gt;      0    1    2    3    4    5    6    7&lt;br /&gt; 0 80BC 7844 7E24 7FD4 7EBC 8090 8138 8044&lt;br /&gt; 1 7FB0 8138 7A90 7EB0 7D54 7F04 7FE4 8074&lt;br /&gt; 2 7F20 7F30 81A4 8018 80C4 7FB4 7F08 7EF8&lt;br /&gt; 3 7F30 8180 7D10 7EA0 6F40 7E30 85E0 79E0&lt;br /&gt; 4 7EA8 7B1C 8240 7FD4 7DE4 7F24 7F44 80C4&lt;br /&gt; 5 A2C0 6D00 6CC0 69E0 6700 7F28 &lt;span style="background-color:orange; color:white;"&gt;5E00&lt;/span&gt; 4E00&lt;br /&gt; 6 7F5C 7ECC 7FB8 7FF8 7C38 7FF0 7EF0 7CAC&lt;br /&gt; 7 7FD0 7D80 8168 8058 8104 7FA0 7FAC 80E8&lt;br /&gt; 8 71E0 &lt;span style="background-color:red; color:white;"&gt;B500&lt;/span&gt; 8E80 8020 7900 8124 7980 8240&lt;br /&gt; 9 7A20 6E40 7AE0 7FA8 8080 7F84 8240 88E0&lt;br /&gt;10 7930 6900 7A50 81BC 7220 7C48 7A20 6FC0&lt;br /&gt;11 7950 8C00 7600 8054 6F20 806C 7CE0 89C0&lt;br /&gt;12 6F40 &lt;span style="background-color:red; color:white;"&gt;4B00&lt;/span&gt; 85C0 8010 7600 809C 7E00 7E80&lt;br /&gt;13 7F30 7B20 7FB8 8028 803C 80B4 7E80 8140&lt;br /&gt;14 7A90 8034 7D4C 8124 80D8 7E8C 7FC8 7FC0&lt;br /&gt;15 73F0 79C0 7990 80D0 9440 7D94 7AC0 6EA0&lt;br /&gt;&lt;br /&gt;      8    9   10   11   12   13   14   15&lt;br /&gt; 0 8048 7E84 7DB8 801C 80B8 80A4 62BC 7FB0&lt;br /&gt; 1 803C 7FE8 7E20 81E8 80F0 7D68 8144 7FBC&lt;br /&gt; 2 807C 80C4 7F80 7FFC 7F90 7EE0 82B0 80B4&lt;br /&gt; 3 7EB0 80E0 7E68 7F70 7E78 8010 7580 7BBC&lt;br /&gt; 4 7FF0 7F68 7FB8 7FFC 7FAC 8074 7DD4 813C&lt;br /&gt; 5 7F08 6FA0 7254 6BB8 6C10 &lt;span style="background-color:orange; color:white;"&gt;6380&lt;/span&gt; 6300 7AE8&lt;br /&gt; 6 7FF4 7F9C 8018 7FCC 8138 8118 6E14 80BC&lt;br /&gt; 7 8088 80DC 7FC0 7DB8 7F8C 7EE4 84E0 7F48&lt;br /&gt; 8 7EEC 8090 84EC 7E28 8328 8960 &lt;span style="background-color:red; color:white;"&gt;2D00&lt;/span&gt; 85AC&lt;br /&gt; 9 7F94 7EA4 7D6C 8080 8068 8200 5FC0 82F0&lt;br /&gt;10 7AF0 80AC 80C8 7CB4 8054 8640 7100 7F8C&lt;br /&gt;11 81F0 8080 7F2C 8064 7F94 82C0 6E80 7B30&lt;br /&gt;12 809C 7FD0 7F98 7ED0 75C8 83C0 &lt;span style="background-color:red; color:white;"&gt;D300&lt;/span&gt; 7CE8&lt;br /&gt;13 8134 8160 80A0 7F40 7D6C 809C 80E4 7F58&lt;br /&gt;14 7F68 7F14 7F44 7F28 8010 7EB4 7F10 7F80&lt;br /&gt;15 82E0 7D4C 78D8 804C 8000 78A0 6240 75DC&lt;/pre&gt;&lt;br /&gt;The values highlighted in orange are the only two that are constant in every table (there were four in the inverse table).&lt;br /&gt;&lt;br /&gt;But the values highlighted in red are the most interesting. They are not constant--they can vary among a few possible values. But the &lt;b&gt;sum&lt;/b&gt; of the two values in each column is constant, and it's always 0x10000.&lt;br /&gt;&lt;br /&gt;Why? I have no idea.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10457042-116647921308918460?l=mamelife.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mamelife.blogspot.com/feeds/116647921308918460/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10457042&amp;postID=116647921308918460' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/116647921308918460'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/116647921308918460'/><link rel='alternate' type='text/html' href='http://mamelife.blogspot.com/2006/12/cps2-notes-part-3.html' title='CPS2 notes, part 3'/><author><name>Nicola Salmoria</name><uri>http://www.blogger.com/profile/06048642443376701628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10457042.post-116645361152953333</id><published>2006-12-18T14:32:00.000+01:00</published><updated>2006-12-18T22:34:05.806+01:00</updated><title type='text'>CPS2 notes, part 2</title><content type='html'>The 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.&lt;br /&gt;&lt;br /&gt;Let's recap the basics of the CPS2 encryption first.&lt;br /&gt;&lt;br /&gt;Inputs:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;16-bit value stored in ROM&lt;/li&gt;&lt;br /&gt;&lt;li&gt;16-bit address (bits 1-17 of the physical address)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;key of unknown size, different for every game&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Outputs:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;16-bit decrypted value&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;Let's call D(X,A,K) the decryption of value X at address A using key K.&lt;br /&gt;The complementation property says that for every A there is exactly one A&lt;sub&gt;1&lt;/sub&gt; such that&lt;br /&gt;&lt;br /&gt;D(X,A,K) = D'(X',A&lt;sub&gt;1&lt;/sub&gt;,K)&lt;br /&gt;&lt;br /&gt;where x' is the complement of x.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;Unfortunately we don't yet know how to calculate A&lt;sub&gt;1&lt;/sub&gt; given A. It varies from game to game so it must be a function of the key.&lt;br /&gt;&lt;br /&gt;The complementation property isn't unheard of, even in strong ciphers, so it isn't necessarily a weakness in the algorithm. For example, &lt;a href="http://en.wikipedia.org/wiki/Data_Encryption_Standard#Minor_cryptanalytic_properties"&gt;DES&lt;/a&gt; has it. In that case, it reads D(X,K) = D'(X',K').&lt;br /&gt;&lt;br /&gt;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&lt;br /&gt;&lt;br /&gt;d = e XOR f(e XOR k)&lt;br /&gt;&lt;br /&gt;if we take the complements we have&lt;br /&gt;&lt;br /&gt;e' XOR f(e' XOR k') = e' XOR f(e XOR k) = (e XOR f(e XOR k))' = d'&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;A more realistic example would be a &lt;a href="http://en.wikipedia.org/wiki/Feistel_cipher"&gt;Feistel network&lt;/a&gt; (note that DES is an example of a Feistel network).&lt;br /&gt;&lt;br /&gt;If you define the Feistel network as&lt;br /&gt;L&lt;sub&gt;i&lt;/sub&gt; = R&lt;sub&gt;i-1&lt;/sub&gt;&lt;br /&gt;R&lt;sub&gt;i&lt;/sub&gt; = L&lt;sub&gt;i-1&lt;/sub&gt; XOR f(R&lt;sub&gt;i-1&lt;/sub&gt; XOR K&lt;sub&gt;i-1&lt;/sub&gt;)&lt;br /&gt;&lt;br /&gt;it should be easy to see how the complementation property would ensue.&lt;br /&gt;&lt;br /&gt;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 &lt;a href="http://mamelife.blogspot.com/2006/12/cps2-notes-part-1.html"&gt;part 1&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10457042-116645361152953333?l=mamelife.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mamelife.blogspot.com/feeds/116645361152953333/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10457042&amp;postID=116645361152953333' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/116645361152953333'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/116645361152953333'/><link rel='alternate' type='text/html' href='http://mamelife.blogspot.com/2006/12/cps2-notes-part-2.html' title='CPS2 notes, part 2'/><author><name>Nicola Salmoria</name><uri>http://www.blogger.com/profile/06048642443376701628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10457042.post-116638814741570160</id><published>2006-12-17T20:38:00.000+01:00</published><updated>2006-12-18T22:34:01.680+01:00</updated><title type='text'>CPS2 notes, part 1</title><content type='html'>Since the finding of the &lt;a href="http://mamelife.blogspot.com/2006/01/8gb-2-is-still-4gb.html"&gt;complementation property&lt;/a&gt; almost one year ago, there has been no progress at all on the CPS2 encryption.&lt;br /&gt;&lt;br /&gt;I'm going to explain here some of the (remarkably few) things we know about the encryption.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;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.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;       0      1      2      3      4      5      6      7 &lt;br /&gt; 0 50,26% &lt;span style="color:brown"&gt;44,09%&lt;/span&gt; 50,98% 49,68% &lt;span style="color:brown"&gt;42,94%&lt;/span&gt; 50,81% &lt;span style="color:brown"&gt;44,99%&lt;/span&gt; &lt;span style="color:brown"&gt;43,87%&lt;/span&gt;&lt;br /&gt; 1 49,52% 49,73% 49,87% 49,90% 49,32% 49,77% 45,37% 50,43%&lt;br /&gt; 2 49,62% 50,05% 49,67% 50,25% 51,56% 49,86% 49,07% 50,07%&lt;br /&gt; 3 &lt;span style="color:white; background-color:red"&gt;44,53%&lt;/span&gt; 45,75% 48,05% 48,93% &lt;span style="color:brown"&gt;40,63%&lt;/span&gt; 50,22% &lt;span style="color:brown"&gt;69,73%&lt;/span&gt; &lt;span style="color:brown"&gt;44,29%&lt;/span&gt;&lt;br /&gt; 4 49,83% 50,19% 49,62% 49,98% 48,35% 49,88% 50,38% 50,57%&lt;br /&gt; 5 50,24% 46,53% 50,78% 50,21% &lt;span style="color:brown"&gt;28,13%&lt;/span&gt; 49,79% &lt;span style="color:brown"&gt;44,63%&lt;/span&gt; 47,80%&lt;br /&gt; 6 51,92% 49,73% 50,10% 50,17% &lt;span style="color:brown"&gt;38,28%&lt;/span&gt; 50,10% 48,35% 47,86%&lt;br /&gt; 7 50,29% 49,51% 49,16% 49,86% 48,35% 49,93% 50,85% 50,07%&lt;br /&gt; 8 51,95% 52,51% 51,37% 48,71% 49,22% 50,07% 43,55% 46,78%&lt;br /&gt; 9 &lt;span style="color:white; background-color:red"&gt;31,45%&lt;/span&gt; 48,32% &lt;span style="color:brown"&gt;75,00%&lt;/span&gt; &lt;span style="color:brown"&gt;43,55%&lt;/span&gt; 46,39% 50,51% &lt;span style="color:brown"&gt;28,13%&lt;/span&gt; 46,92%&lt;br /&gt;10 50,20% 50,95% 51,37% 49,78% &lt;span style="color:brown"&gt;28,13%&lt;/span&gt; 50,06% 47,17% 51,66%&lt;br /&gt;11 45,17% 45,85% 47,66% 50,38% &lt;span style="color:brown"&gt;25,20%&lt;/span&gt; 50,58% 44,43% 53,37%&lt;br /&gt;12 47,85% 47,51% &lt;span style="color:brown"&gt;44,14%&lt;/span&gt; 50,04% 53,03% 49,24% &lt;span style="color:brown"&gt;38,28%&lt;/span&gt; 49,17%&lt;br /&gt;13 49,68% 49,90% 49,43% 50,10% 50,02% 49,46% 50,05% 49,89%&lt;br /&gt;14 49,35% 50,32% 49,98% 49,80% 48,29% 49,65% 49,48% 50,42%&lt;br /&gt;15 48,97% 51,59% 51,07% 49,57% &lt;span style="color:brown"&gt;67,19%&lt;/span&gt; 49,55% 45,70% 50,39%&lt;br /&gt;&lt;br /&gt;    8      9     10     11     12     13     14     15&lt;br /&gt; 0 50,43% 48,46% 49,02% 49,49% 49,21% &lt;span style="color:brown"&gt;43,35%&lt;/span&gt; 49,05% 47,69%&lt;br /&gt; 1 49,85% 49,69% 50,57% 49,76% 50,01% 49,40% 49,88% 50,15%&lt;br /&gt; 2 50,14% 50,05% 49,86% 49,57% 50,25% 50,96% 48,99% 50,18%&lt;br /&gt; 3 49,46% 50,18% 48,31% 50,30% 46,96% &lt;span style="color:brown"&gt;40,63%&lt;/span&gt; &lt;span style="color:white; background-color:red"&gt;35,35%&lt;/span&gt; &lt;span style="color:brown"&gt;44,34%&lt;/span&gt;&lt;br /&gt; 4 49,82% 50,43% 49,70% 50,34% 49,79% 47,74% 50,16% 49,57%&lt;br /&gt; 5 49,91% 48,74% 49,68% 49,88% 48,79% &lt;span style="color:brown"&gt;28,91%&lt;/span&gt; 49,02% 48,36%&lt;br /&gt; 6 49,74% 49,21% 50,24% 49,62% 49,40% &lt;span style="color:brown"&gt;39,32%&lt;/span&gt; 49,91% 49,62%&lt;br /&gt; 7 50,14% 50,03% 49,63% 50,39% 49,65% 47,67% 50,43% 49,37%&lt;br /&gt; 8 49,83% 49,96% 48,57% 50,43% 49,15% &lt;span style="color:brown"&gt;40,63%&lt;/span&gt; 46,97% 50,50%&lt;br /&gt; 9 50,15% 49,08% &lt;span style="color:brown"&gt;44,80%&lt;/span&gt; 48,27% 49,65% 50,78% &lt;span style="color:white; background-color:red"&gt;34,38%&lt;/span&gt; 50,81%&lt;br /&gt;10 49,76% 49,92% 50,28% 49,24% 49,21% &lt;span style="color:brown"&gt;67,97%&lt;/span&gt; 49,27% 49,87%&lt;br /&gt;11 47,55% 50,00% 50,16% 47,17% 49,61% &lt;span style="color:brown"&gt;25,39%&lt;/span&gt; 48,93% 51,68%&lt;br /&gt;12 49,83% 48,97% 49,69% 49,86% 49,30% 52,93% 50,39% 49,90%&lt;br /&gt;13 49,85% 50,37% 50,52% 49,94% 49,60% 51,22% 49,96% 49,92%&lt;br /&gt;14 49,85% 50,18% 49,97% 49,89% 50,09% 49,84% 47,50% 49,64%&lt;br /&gt;15 49,49% 49,37% 49,39% 50,09% 49,57% &lt;span style="color:brown"&gt;38,28%&lt;/span&gt; 49,17% 49,57%&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;So there is a large number of values around 50%, which look just random, but there are also values very far from that.&lt;br /&gt;&lt;br /&gt;This indicates that the encryption algorithm &lt;em&gt;doesn't have good &lt;a href="http://en.wikipedia.org/wiki/Confusion_and_diffusion"&gt;diffusion&lt;/a&gt;&lt;/em&gt;. This is a weakness, though it hasn't been exploited yet.&lt;br /&gt;&lt;br /&gt;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 &lt;em&gt;are always the same&lt;/em&gt;. 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.&lt;br /&gt;&lt;br /&gt;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 &lt;em&gt;when&lt;/em&gt; to flip them. Discovering that would be a significant advance in the understanding of the algorithm.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10457042-116638814741570160?l=mamelife.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mamelife.blogspot.com/feeds/116638814741570160/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10457042&amp;postID=116638814741570160' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/116638814741570160'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/116638814741570160'/><link rel='alternate' type='text/html' href='http://mamelife.blogspot.com/2006/12/cps2-notes-part-1.html' title='CPS2 notes, part 1'/><author><name>Nicola Salmoria</name><uri>http://www.blogger.com/profile/06048642443376701628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10457042.post-116559557930771739</id><published>2006-12-08T15:31:00.000+01:00</published><updated>2006-12-17T21:43:39.536+01:00</updated><title type='text'>Katamino</title><content type='html'>(This article is not MAME related)&lt;br /&gt;&lt;br /&gt;Some time ago I was shopping looking for a set of &lt;a href="http://en.wikipedia.org/wiki/Pentomino"&gt;Pentomino&lt;/a&gt; pieces and found this game called &lt;a href="http://www.katamino.co.uk/"&gt;Katamino®&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;The idea is credited to André Perriolat, who is the owner of the company that produces the game, &lt;a href="http://www.katamino.com"&gt;DJ Games&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;In the box there's a list of 12 such sequences that you can follow, each one ending with a different piece.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;build 12 sequences, each one ending with a different piece&lt;/li&gt;&lt;br /&gt;&lt;li&gt;every combination of pieces must be used only once&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;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).&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;With a mix of manual pruning and computer search, I've selected this sequence which looks quite good:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;L P U F [1] W [1] I [4] Z [1] T [5] N [1] V [83] Y [1277] X [786]&lt;br /&gt;L Y U F [3] Z [1] I [2] N [2] T [4] X [2] V [16] P [ 508] W   "&lt;br /&gt;Y N V T [1] F [1] I [3] W [1] U [5] X [1] L [ 8] P [ 371] Z   "&lt;br /&gt;L Y P W [5] N [1] V [1] I [5] X [1] Z [5] F [25] U [ 216] T   "&lt;br /&gt;Y P U F [1] T [1] I [2] Z [1] N [2] X [1] W [ 2] L [ 183] V   "&lt;br /&gt;L Y P T [1] W [1] F [1] N [5] X [3] Z [1] I [ 8] V [ 133] U   "&lt;br /&gt;L V P Z [2] Y [1] T [2] I [5] X [1] W [1] F [15] U [ 125] N   "&lt;br /&gt;L Y P Z [1] W [2] T [1] V [1] X [1] U [3] N [21] I [ 116] F   "&lt;br /&gt;L N P U [2] Z [2] X [1] V [1] F [1] T [2] W [14] Y [ 112] I   "&lt;br /&gt;L N V Z [2] U [1] T [1] F [2] I [6] W [3] X [ 1] P [ 101] Y   "&lt;br /&gt;Y N P U [1] V [1] Z [1] X [1] F [2] T [1] W [ 1] I [  59] L   "&lt;br /&gt;L Y V U [2] Z [1] F [1] W [1] X [1] N [1] T [ 1] I [  14] P   "&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The numbers in square brackets are the solutions for each puzzle.&lt;br /&gt;The total is &lt;b&gt;331&lt;/b&gt; solutions, and &lt;b&gt;45&lt;/b&gt; puzzles with a single solution.&lt;br /&gt;&lt;br /&gt;I think this should be quite close to the minimum, but I don't have a way to prove it.&lt;br /&gt;&lt;br /&gt;Can anyone do better?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10457042-116559557930771739?l=mamelife.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mamelife.blogspot.com/feeds/116559557930771739/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10457042&amp;postID=116559557930771739' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/116559557930771739'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/116559557930771739'/><link rel='alternate' type='text/html' href='http://mamelife.blogspot.com/2006/12/katamino.html' title='Katamino'/><author><name>Nicola Salmoria</name><uri>http://www.blogger.com/profile/06048642443376701628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10457042.post-115478382747358380</id><published>2006-08-05T14:11:00.000+02:00</published><updated>2006-12-08T23:22:07.163+01:00</updated><title type='text'>Completed, at Last</title><content type='html'>As you'd probably noticed, the pics in the previous post are of the Bubble Bobble custom MCU.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;With this ROM, we finally have the final piece of the puzzle for a 100% guaranteed perfect emulation.&lt;br /&gt;&lt;br /&gt;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:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;process coin inputs and update the credit counter&lt;/li&gt;&lt;li&gt;handle the number of remaining lives for both players&lt;/li&gt;&lt;li&gt;handle the current round number&lt;/li&gt;&lt;li&gt;handle variable speed incrementing for four variables&lt;/li&gt;&lt;li&gt;return values from a 1280 bytes table of seemingly random data&lt;/li&gt;&lt;/ul&gt;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).&lt;br /&gt;&lt;br /&gt;So, how close was the simulation to the real thing? Very close; "too good", actually. Let's see why.&lt;br /&gt;&lt;br /&gt;The clock item behaviour was spot on, but off by one frame (the simulation made the counter expire one frame too late).&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;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! :)&lt;br /&gt;Also, new bubbles will not appear if there are already 16 bubbles on the screen, so that will change the order as well.&lt;br /&gt;&lt;br /&gt;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 &gt;, =, or &lt;, 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!&lt;br /&gt;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.&lt;br /&gt;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.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10457042-115478382747358380?l=mamelife.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mamelife.blogspot.com/feeds/115478382747358380/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10457042&amp;postID=115478382747358380' title='12 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/115478382747358380'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/115478382747358380'/><link rel='alternate' type='text/html' href='http://mamelife.blogspot.com/2006/08/completed-at-last.html' title='Completed, at Last'/><author><name>Nicola Salmoria</name><uri>http://www.blogger.com/profile/06048642443376701628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>12</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10457042.post-115463836147849830</id><published>2006-08-03T22:47:00.000+02:00</published><updated>2006-12-08T23:22:00.723+01:00</updated><title type='text'>Good News</title><content type='html'>&lt;p&gt;What's inside this?&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="http://photos1.blogger.com/blogger/6506/809/320/JPH1011P.jpg" alt="JPH1011P" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;This:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="http://photos1.blogger.com/blogger/6506/809/1600/6801U4.jpg" alt="6801U4" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;More on this later.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10457042-115463836147849830?l=mamelife.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mamelife.blogspot.com/feeds/115463836147849830/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10457042&amp;postID=115463836147849830' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/115463836147849830'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/115463836147849830'/><link rel='alternate' type='text/html' href='http://mamelife.blogspot.com/2006/08/good-news.html' title='Good News'/><author><name>Nicola Salmoria</name><uri>http://www.blogger.com/profile/06048642443376701628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10457042.post-115079657902222806</id><published>2006-06-20T11:01:00.000+02:00</published><updated>2006-12-08T23:21:56.086+01:00</updated><title type='text'>Political Digression</title><content type='html'>Forgive me for abusing of this space to talk about an important matter of Italian politics.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;Questo è l'articolo 70 nella nostra Costituzione:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;"La funzione legislativa è esercitata collettivamente dalle due Camere."&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Questo è l'articolo con cui verrebbe sostituito se la nuova Costituzione sarà approvata dal referendum:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;"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.&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;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.&lt;br /&gt;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.&lt;br /&gt;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"&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;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à.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10457042-115079657902222806?l=mamelife.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mamelife.blogspot.com/feeds/115079657902222806/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10457042&amp;postID=115079657902222806' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/115079657902222806'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/115079657902222806'/><link rel='alternate' type='text/html' href='http://mamelife.blogspot.com/2006/06/political-digression.html' title='Political Digression'/><author><name>Nicola Salmoria</name><uri>http://www.blogger.com/profile/06048642443376701628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10457042.post-114073835395219366</id><published>2006-02-24T00:30:00.000+01:00</published><updated>2006-12-08T23:21:52.676+01:00</updated><title type='text'>Still some doubts about Bubble Bobble</title><content type='html'>The emulation of Bubble Bobble is already virtually perfect, but there is still a doubt about the clock item.&lt;br /&gt;&lt;br /&gt;Currently, when you pick it up the enemies stop but the bubbles continue moving.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;What we need is to verify the behaviour on an &lt;strong&gt;original&lt;/strong&gt; 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.&lt;br /&gt;&lt;br /&gt;Can anyone help?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10457042-114073835395219366?l=mamelife.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mamelife.blogspot.com/feeds/114073835395219366/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10457042&amp;postID=114073835395219366' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/114073835395219366'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/114073835395219366'/><link rel='alternate' type='text/html' href='http://mamelife.blogspot.com/2006/02/still-some-doubts-about-bubble-bobble.html' title='Still some doubts about Bubble Bobble'/><author><name>Nicola Salmoria</name><uri>http://www.blogger.com/profile/06048642443376701628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10457042.post-113901340009079322</id><published>2006-02-04T01:11:00.000+01:00</published><updated>2006-12-08T23:21:49.496+01:00</updated><title type='text'>Coinmaster</title><content type='html'>&lt;a href="http://www.citylan.it/reip/"&gt;Pierpaolo Prazzoli&lt;/a&gt; made me look at the encrypted question ROMs of the Coinmaster games.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;To verify the checksum, the game reads all bytes in the ROM &lt;em&gt;except&lt;/em&gt; 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 &lt;em&gt;all&lt;/em&gt; bytes in the ROM will always give as result 0.&lt;br /&gt;&lt;br /&gt;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.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10457042-113901340009079322?l=mamelife.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mamelife.blogspot.com/feeds/113901340009079322/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10457042&amp;postID=113901340009079322' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/113901340009079322'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/113901340009079322'/><link rel='alternate' type='text/html' href='http://mamelife.blogspot.com/2006/02/coinmaster.html' title='Coinmaster'/><author><name>Nicola Salmoria</name><uri>http://www.blogger.com/profile/06048642443376701628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10457042.post-113734445577119227</id><published>2006-01-15T17:59:00.000+01:00</published><updated>2006-12-08T23:21:45.073+01:00</updated><title type='text'>8GB / 2 is still 4GB</title><content type='html'>sfzj_049e38[x] ^ 0xffff == sfzj_05ee0c[x ^ 0xffff]&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10457042-113734445577119227?l=mamelife.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mamelife.blogspot.com/feeds/113734445577119227/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10457042&amp;postID=113734445577119227' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/113734445577119227'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/113734445577119227'/><link rel='alternate' type='text/html' href='http://mamelife.blogspot.com/2006/01/8gb-2-is-still-4gb.html' title='8GB / 2 is still 4GB'/><author><name>Nicola Salmoria</name><uri>http://www.blogger.com/profile/06048642443376701628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10457042.post-113031565288525895</id><published>2005-10-26T10:13:00.000+02:00</published><updated>2006-12-08T23:21:40.656+01:00</updated><title type='text'>Strange that nobody noticed</title><content type='html'>Check the final level of Fairyland Story ending on &lt;a href="http://emulazione.multiplayer.it/mamend/F/flstory.htm"&gt;MamEnd&lt;/a&gt;.&lt;br /&gt;The background graphics are quite obviously broken in the top left corner! Strange that nobody reported this bug.&lt;br /&gt;&lt;br /&gt;Anyway, I've fixed it now.&lt;br /&gt;&lt;br /&gt;I've also been studying what the MCU does in that game, and the programmers made some interesting choices.&lt;br /&gt;&lt;br /&gt;First of all, the MCU can return data stored in its internal ROM. This is done with short tables that are needed at the beginning of a level, and when you die. More interestingly, the text needed for the continue screen is stored there, and since you can't continue until level 8, it would take some time for a bootlegger to notice the problem. Even more interestingly, the endgame text is stored there, so one would have to play all the 101 levels to get to the protection.&lt;br /&gt;&lt;br /&gt;Another wicked part of the MCU protection is that before action starts in a level, the game takes three bytes, performs complicated calculations on them to convert them into an 8-byte number passed to the MCU, and the MCU then performs more complicated calculations, recovers the original bytes and sends them back. A lot of work to essentially do nothing.&lt;br /&gt;&lt;br /&gt;Finally, during the final level, the MCU is used to calculate and update the trajectory of the dragon's fireballs. Without the MCU, the dragon doesn't fire. I just have to wonder: why bother? How many people would have reached the final level in the arcades? And would bootleggers have bothered anyway? Figure some player going to the arcade owner and asking for her quarter back because the ending was too easy :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10457042-113031565288525895?l=mamelife.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mamelife.blogspot.com/feeds/113031565288525895/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10457042&amp;postID=113031565288525895' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/113031565288525895'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/113031565288525895'/><link rel='alternate' type='text/html' href='http://mamelife.blogspot.com/2005/10/strange-that-nobody-noticed.html' title='Strange that nobody noticed'/><author><name>Nicola Salmoria</name><uri>http://www.blogger.com/profile/06048642443376701628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10457042.post-111523248855206946</id><published>2005-05-04T20:24:00.000+02:00</published><updated>2006-12-08T23:21:38.643+01:00</updated><title type='text'>Snowball effect</title><content type='html'>As you might already have seen on &lt;a href="http://haze.mameworld.info/2005/05/04/space-position/"&gt;Haze's WIP&lt;/a&gt;, yesterday I succeeded in decrypting Gardia and Space Position.&lt;br /&gt;&lt;br /&gt;This was an interesting case of pieces falling into place rapidly one after another.&lt;br /&gt;&lt;br /&gt;The first piece was the decryption of Calorie Kun, thanks to a decrypted bootleg which was recently found. This didn't look like a particolarly interesting breakthrough at the moment: the encryption algorythm was already known, the key would have been difficult to find by hand but with the reference of the bootleg it could be derived automatically in a few minutes - just the time to write a program.&lt;br /&gt;&lt;br /&gt;This renewed my interest in the remaining Sega encrypted games that use this algorithm, in particular Gardia. David Widel revealed that he had decrypted a portion of it months ago, but got stuck and put aside the results without publishing them. Believe it or not, he decrypted most of the code by comparing it with My Hero - even if that's a completely different game, it shares a lot of almost identical code with Gardia.&lt;br /&gt;&lt;br /&gt;The data David provided was very useful to get started. Another really useful coincidence was that we have two sets of Gardia (one supposedly being a bootleg, but still encrypted). The two sets are different versions, with code shifted by a few bytes in places. This is an ideal situation when decrypting games that use simple algorithms like this one. When you have decrypted a portion of code in one set, you can use it to decrypt the same portion of code in the other set; but this way you also automatically decrypt some more code in the second set, which is still encrypted in the first set, so you can go back to the first set and decrypt even more code, and so on - you slowly build up the two keys in parallel.&lt;br /&gt;&lt;br /&gt;While I was doing this, I rapidly noticed that the key used by the second set for opcodes was identical to the one used by the first set for data. Shortly afterwards, I also noticed that the key used by the second set for data was identical to the one used by the first set for opcodes - just shifted by one byte.&lt;br /&gt;&lt;br /&gt;At that point I was on the lookout; I have to admit that I didn't notice it immediately, but eventually I discovered that the keys were actually the same as Calorie Kun, apart from the shift. When I found that, I just copied the whole Calorie Kun keys and I was almost finished - Gardia booted but had some problems. I just had to find a few more bytes at the end of the key to fix them.&lt;br /&gt;&lt;br /&gt;Space Position was the easiest of all. At that point I was almost sure it would have used the same key. I checked some bytes of the partial key I had manually derived years ago, matched them with the known key, copied over the data with the appropriate shift, launched the game, and it was already working, on the first try - apart from the emulation issues which Haze later fixed.&lt;br /&gt;&lt;br /&gt;This completes the decryption of all currently known Sega games using the "easy" Z80 encryptions. Unfortunately there are a few encrypted Z80 games left, using the suicide MC8123 CPU, which might be lost forever: all boards using the CPU seem to be dead, and the key is just about impossible to find without an hardware attack.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10457042-111523248855206946?l=mamelife.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mamelife.blogspot.com/feeds/111523248855206946/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10457042&amp;postID=111523248855206946' title='14 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/111523248855206946'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/111523248855206946'/><link rel='alternate' type='text/html' href='http://mamelife.blogspot.com/2005/05/snowball-effect.html' title='Snowball effect'/><author><name>Nicola Salmoria</name><uri>http://www.blogger.com/profile/06048642443376701628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>14</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10457042.post-111412088927081097</id><published>2005-04-22T00:00:00.000+02:00</published><updated>2006-12-08T23:21:34.840+01:00</updated><title type='text'>Easier than expected</title><content type='html'>Bryan noticed that changing a single value in the Pocket Gal Deluxe decryption (related to the address scrambling) revealed some clear text in Diet Go Go. THis means that the encryption key is almost hardcoded as I expected, but with some minor variation (maybe externally to the DE102 iself).&lt;br /&gt;&lt;br /&gt;I have isolated the variations in just two numbers, a 16-bit one for the address scrambling and an 8-bit one (or two 4-bit ones) for the data bits permutation and xor.&lt;br /&gt;&lt;br /&gt;Fine tuning the values to correctly decrypt data in Diet Go Go was easy enough.&lt;br /&gt;&lt;br /&gt;Double Wings required a little more works, but it was still easy. I just needed to brute force the 16-bit parameter. Doing that was easy because I just had to decrypt the ROM using each possible value for the parameter, and count how many zeros were in the decrypted data. When their number rised from a couple of thousands to tens of thousand, I had a "good enough" value for the parameter, which I could later tweak by hand.&lt;br /&gt;&lt;br /&gt;So, data was decrypted in all four games (the other one is Boogie Wings which decrypted with the same parameters as Pocket Gal Deluxe), but opcodes were still encrypted.&lt;br /&gt;&lt;br /&gt;However, most of the work was already done. Even if the opcodes are encrypted differently from data, the address scrambling must of course be the same, otherwise there wouldn't be a 1:1 correlation between logical address and physical address. Therefore, only the data bits permutation and xor changes.&lt;br /&gt;The obvious candidate for that variation was the 8-bit parameter. A brute force search was even easier in this case. I just had to try all possible values and count how many times 4E75 (the opcode for RTS) appeared. When it increased from a couple of times to several hundreds, I had the key.&lt;br /&gt;&lt;br /&gt;So all four known games using this CPU (Pocket Gal Deluxe, Diet Go Go, Double Wings and Boogie Wings) should now be fully decrypted.&lt;br /&gt;Non of them is working; for that, the driver will have to be finished, and possibly some more protection worked around. But the first hurdle has been overcome.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10457042-111412088927081097?l=mamelife.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mamelife.blogspot.com/feeds/111412088927081097/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10457042&amp;postID=111412088927081097' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/111412088927081097'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/111412088927081097'/><link rel='alternate' type='text/html' href='http://mamelife.blogspot.com/2005/04/easier-than-expected.html' title='Easier than expected'/><author><name>Nicola Salmoria</name><uri>http://www.blogger.com/profile/06048642443376701628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10457042.post-111402650929338057</id><published>2005-04-20T21:28:00.000+02:00</published><updated>2006-12-08T23:21:31.390+01:00</updated><title type='text'>DE102</title><content type='html'>The recent discovery of a decrypted bootleg of Pocket Gal Deluxe was a pleasant surprise. This is one of a handful of games that use the same encrypted custom CPU - called DE102.&lt;br /&gt;It is now confirmed that the CPU is a 68000.&lt;br /&gt;&lt;br /&gt;Thanks to the bootleg, I was able to figure out the decryption algorithm. It is quite straightforward, and it involves:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Address scrambling. When the CPU wants to read a word from logical address &lt;em&gt;N&lt;/em&gt;, it fetches it from ROM space at address &lt;em&gt;N'.&lt;/em&gt; The scrambling of the address requires 16 conditional XORs with 16-bit values.&lt;/li&gt;&lt;li&gt;Data bits permutation. After reading the word from ROM, the order of its bits is altered. There are 16 possible permutations; which one to use depends trivially on the logical address.&lt;/li&gt;&lt;li&gt;Data XOR. After changing the bit order, the value is XORed with one of 16 other values. Which one to use depends trivially on the logical address.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;While working on Pcket Gal Deluxe, I was hoping that the DE102 would use a fixed key, which would have emant free decryption of a few other games. Unfortunately, this turned out to not be the case. The algorithm surely is the same, but the key is different.&lt;/p&gt;&lt;p&gt;Determining the key without having a decrypted version to compare with is a lot more difficult, as you can imagine. Also, it seems that at least one of the other games encrypts data and opcodes differently, which makes things a lot more complicated.&lt;/p&gt;&lt;p&gt;In the next days, I'll see if I can find a way to break the key somehow.&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10457042-111402650929338057?l=mamelife.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mamelife.blogspot.com/feeds/111402650929338057/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10457042&amp;postID=111402650929338057' title='13 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/111402650929338057'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/111402650929338057'/><link rel='alternate' type='text/html' href='http://mamelife.blogspot.com/2005/04/de102.html' title='DE102'/><author><name>Nicola Salmoria</name><uri>http://www.blogger.com/profile/06048642443376701628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>13</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10457042.post-111322175291739373</id><published>2005-04-11T14:03:00.000+02:00</published><updated>2006-12-08T23:21:28.513+01:00</updated><title type='text'>Great Swordsman colors</title><content type='html'>Sprite colors in Great Swordsman have been one of the longest standing and most elusive emulation imperfections to date.&lt;br /&gt;It was hardly noticeable, because a manually crafted lookup table had been crafted in the driver, so colors looked ok.&lt;br /&gt;&lt;br /&gt;Finally, thanks to Kold666's invaluable help, the emulation is now perfect.&lt;br /&gt;As you can see in the shots, the difference is subtle but it's there. It is probably most evident on the pulsing logo, whose color changes are now slightly smoother.&lt;br /&gt;&lt;br /&gt;&lt;img alt="Great Swordsman before the fix" src="http://photos1.blogger.com/blogger/6506/809/400/gsword_before.png" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;img alt="Great Swordsman after the fix" src="http://photos1.blogger.com/blogger/6506/809/400/gsword_after.png" /&gt;&lt;br /&gt;&lt;br /&gt;The way how I achieved this is worth of mention. Kold kindly provided some pictures of the pcb (parts side and solder side). I x-flipped the solder side, overlapped them in a gfx editing program, and carefully aligned them so I could see both layers at once. Then started tracing from the color lookup PROM, to see what the board does with the data.&lt;br /&gt;&lt;br /&gt;In the end, it turned out that the sprite palette data comes from a row of the character palette, the tricky part being that the order of the 4 bits coming out from the lookup PROM is reversed. This is something that could have been noticed before, but it always eluded me.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10457042-111322175291739373?l=mamelife.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mamelife.blogspot.com/feeds/111322175291739373/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10457042&amp;postID=111322175291739373' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/111322175291739373'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/111322175291739373'/><link rel='alternate' type='text/html' href='http://mamelife.blogspot.com/2005/04/great-swordsman-colors.html' title='Great Swordsman colors'/><author><name>Nicola Salmoria</name><uri>http://www.blogger.com/profile/06048642443376701628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10457042.post-111309662905056848</id><published>2005-04-10T03:25:00.000+02:00</published><updated>2006-12-08T23:21:25.443+01:00</updated><title type='text'>Panic Road</title><content type='html'>I didn't have much time for MAME in the past few weeks, but tonight I could finally do something again.&lt;br /&gt;&lt;br /&gt;This time I decrypted the graphics for Panic Road. The encryption is just a simple data and address lines swap, so it wasn't particularly hard to do - but it took some time nevertheless.&lt;br /&gt;&lt;br /&gt;I don't have time to finish the driver, this will be a job for someone else.&lt;br /&gt;&lt;br /&gt;&lt;img alt="Panic Road" src="http://xoomer.virgilio.it/nicola.salmoria/panicr.png" /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10457042-111309662905056848?l=mamelife.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mamelife.blogspot.com/feeds/111309662905056848/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10457042&amp;postID=111309662905056848' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/111309662905056848'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/111309662905056848'/><link rel='alternate' type='text/html' href='http://mamelife.blogspot.com/2005/04/panic-road.html' title='Panic Road'/><author><name>Nicola Salmoria</name><uri>http://www.blogger.com/profile/06048642443376701628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10457042.post-111151565718842774</id><published>2005-03-22T19:07:00.000+01:00</published><updated>2006-12-08T23:21:21.463+01:00</updated><title type='text'>How to dump a NMK004</title><content type='html'>This is still at the theorical level, until one of the hardware gurus gets his hands dirty and tries to put it in practice.&lt;br /&gt;&lt;br /&gt;The NMK004 cannot be dumped directly using the common methods, but the way it operates can probably be used to extract the internal ROM data in another way.&lt;br /&gt;&lt;br /&gt;The external ROM contains data tables used to play the samples and music; but not only that, it contains pointers to those tables.&lt;br /&gt;By changing those pointers, we can make the NMK004 use its internal ROM as if it was one of the external tables. In particular, this can be done with the table that contains the sample numbers to be played by the two OKI6295.&lt;br /&gt;&lt;br /&gt;We can then log the commands sent by the NMK004 to the OKI6295, and this will allow us to determine which sample it is attempting to play - and therefore the value of the internal ROM byte it has just read.&lt;br /&gt;&lt;br /&gt;So in theory there shouldn't be problems - unfortunately the hardware setup needed to get it all to work isn't trivial. But I'm confident that in due time it will be done.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10457042-111151565718842774?l=mamelife.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mamelife.blogspot.com/feeds/111151565718842774/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10457042&amp;postID=111151565718842774' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/111151565718842774'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/111151565718842774'/><link rel='alternate' type='text/html' href='http://mamelife.blogspot.com/2005/03/how-to-dump-nmk004.html' title='How to dump a NMK004'/><author><name>Nicola Salmoria</name><uri>http://www.blogger.com/profile/06048642443376701628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10457042.post-111107010528396526</id><published>2005-03-17T14:39:00.000+01:00</published><updated>2006-12-08T23:21:18.566+01:00</updated><title type='text'>NMK004 update</title><content type='html'>As most of you have already seen, a few days ago Haze released an &lt;a href="http://haze.mameworld.info/weblog/archives/2005/03/094u2_094u3.html"&gt;update&lt;/a&gt; with the first version of my NMK004 simulation code.&lt;br /&gt;&lt;br /&gt;All NMK004 games have sound, though in some of them it's better than in others. Mustang is possibly the worst one - I have doubts about the sound ROM being a bad dump.&lt;br /&gt;&lt;br /&gt;There were a few major problems - music stopping shortly after starting, or games completely freezing MAME. I have found a bug in the loops handling which should have caused most of these problems. Here is the &lt;a href="http://xoomer.virgilio.it/nicola.salmoria/nmk004.zip"&gt;fix&lt;/a&gt;. It doesn't improve Mustang, though.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10457042-111107010528396526?l=mamelife.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mamelife.blogspot.com/feeds/111107010528396526/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10457042&amp;postID=111107010528396526' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/111107010528396526'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/111107010528396526'/><link rel='alternate' type='text/html' href='http://mamelife.blogspot.com/2005/03/nmk004-update.html' title='NMK004 update'/><author><name>Nicola Salmoria</name><uri>http://www.blogger.com/profile/06048642443376701628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10457042.post-111071779149179392</id><published>2005-03-13T13:00:00.000+01:00</published><updated>2006-12-08T23:21:14.853+01:00</updated><title type='text'>Digital Fortress</title><content type='html'>Which is the book I'm reading now.&lt;br /&gt;&lt;br /&gt;I really don't have much time to read, as you can imagine working on MAME eats up most of my spare time. However I try to read something even if it means just a couple of pages per day.&lt;br /&gt;&lt;br /&gt;I had read the bestseller &lt;em&gt;The Da Vinci Code&lt;/em&gt; previously, and didn't feel any urge to read another book from the same author, especially after I noticed that all bookstores are now prominently displaying his previous works, which had went entirely unnoticed until the success of &lt;em&gt;The Da Vinci Code&lt;/em&gt;.&lt;br /&gt;&lt;br /&gt;&lt;em&gt;Digital Fortress&lt;/em&gt; in particular was written in 1998. The publisher must have been unable to find any positive review to reprint on the back cover, because they resorted to quoting "Praise for &lt;em&gt;The Da Vinci Code&lt;/em&gt;". However I was intrigued bu the theme of the book, which is cryptography - and I was able to borrow it from a friend, so I gave it a try :)&lt;br /&gt;&lt;br /&gt;The problem with fiction is that you must be able to suspend disbelief to immerse in the story. This isn't easy if what is being thrown at you makes no sense at all. This was also a problem with &lt;em&gt;The Da Vinci Code&lt;/em&gt;, of course, but not knowing much about art history it was easier to fool me. Mathematics is supposed to be my field, so fooling me gets a little bit harder.&lt;br /&gt;&lt;br /&gt;Right at the beginning of the book, on page 29, the author introduces Julius Caesar as "the first code-writer in history", and talks about a "'perfect square' cipher box" he supposedly use. This is a transposition cipher, which consists of arranging the cleartext in a square and reading it by columns to get the ciphertext.&lt;br /&gt;&lt;br /&gt;Well, I had never heard of this "Caesar's box" cipher. The encryption commonly associated with Caesar is the one called "Caesar's cipher", and it is a substitution cipher: replace every letter with the one &lt;em&gt;k&lt;/em&gt; places after it in the alphabet, so e.g. A becomes D, B becomes E, and so on.&lt;br /&gt;A transposition cipher similar to the one mentioned by Dan Brown was used in Sparta, a few centuries before Caesar's birth.&lt;br /&gt;&lt;br /&gt;OK, never mind. After all, I might just be ignorant not knowing about the Caesar's Box. Unfortunately, on page 34 Dan Brown talks about public-key encryption, and what he says makes little sense.&lt;br /&gt;&lt;br /&gt;The comment that modern codes are "computer-generated has functions that employed chaos theory and multiple symbolic alphabets" was also funny - it reminded me of &lt;a href="http://www.hypertrek.org/etc/generator.html"&gt;this&lt;/a&gt; :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10457042-111071779149179392?l=mamelife.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mamelife.blogspot.com/feeds/111071779149179392/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10457042&amp;postID=111071779149179392' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/111071779149179392'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/111071779149179392'/><link rel='alternate' type='text/html' href='http://mamelife.blogspot.com/2005/03/digital-fortress.html' title='Digital Fortress'/><author><name>Nicola Salmoria</name><uri>http://www.blogger.com/profile/06048642443376701628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10457042.post-111015811253500731</id><published>2005-03-07T01:43:00.000+01:00</published><updated>2006-12-08T23:21:10.890+01:00</updated><title type='text'>Almost good enough</title><content type='html'>I am at a point that I almost consider good enough. The FM part is supported as well. The state machine seems to produce the correct notes, the only strange thing is that the volume is extremely low - I had to push it to 2.0 gain and lower all the others to make it reasonable. There might be a bug somewhere in the way the FM parameters are set - this stuff is much more complex than the PSG.&lt;br /&gt;&lt;br /&gt;At this point, I'm more worried about the protection in some games than by the sound, which is coming along nicely.&lt;br /&gt;&lt;br /&gt;It has to be said that this simulation I've written was mostly for personal education and for reference. I am 99% certain the the NMK004 internal ROM can be extracted, using a technique I thought of. Theoretically it's very simple, but the process will require some hardware work.&lt;br /&gt;&lt;br /&gt;And of course, once the ROM is extracted, we'll have to see if it can be ran in MAME. It supposedly is a TLCS-90, which is one of the few CPUs not yet supported by MAME, so an emulator for that CPU would have to be written. Which would be a good thing because it would also allow to support Mahjong If and sound in Rapid Hero.&lt;br /&gt;Having the simulation code available might help while writing the CPU emulator.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10457042-111015811253500731?l=mamelife.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mamelife.blogspot.com/feeds/111015811253500731/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10457042&amp;postID=111015811253500731' title='14 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/111015811253500731'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/111015811253500731'/><link rel='alternate' type='text/html' href='http://mamelife.blogspot.com/2005/03/almost-good-enough.html' title='Almost good enough'/><author><name>Nicola Salmoria</name><uri>http://www.blogger.com/profile/06048642443376701628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>14</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10457042.post-111012948170541811</id><published>2005-03-06T18:16:00.000+01:00</published><updated>2006-12-08T23:21:08.043+01:00</updated><title type='text'>Polyphony</title><content type='html'>The problems with the PSG notes were just caused by a silly omission of a *2 in a table lookup. Things that happen when hacking around at 4AM ;)&lt;br /&gt;&lt;br /&gt;The PSG part sounds quite good now. Only the FM part is missing...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10457042-111012948170541811?l=mamelife.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mamelife.blogspot.com/feeds/111012948170541811/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10457042&amp;postID=111012948170541811' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/111012948170541811'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/111012948170541811'/><link rel='alternate' type='text/html' href='http://mamelife.blogspot.com/2005/03/polyphony.html' title='Polyphony'/><author><name>Nicola Salmoria</name><uri>http://www.blogger.com/profile/06048642443376701628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10457042.post-111012663089146037</id><published>2005-03-06T17:16:00.000+01:00</published><updated>2006-12-08T23:20:58.006+01:00</updated><title type='text'>Cacophony</title><content type='html'>Things are going rather well with the NMK004 simulation.&lt;br /&gt;&lt;br /&gt;The NMK004 state machine supports:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Six FM channels; each pair of them shares one of the three YM2203 voices.&lt;/li&gt;&lt;li&gt;Three PSG channels, each one using one of the PSG voices of the YM2203.&lt;/li&gt;&lt;li&gt;Eight Effects channels, which can use the total eight voices provided by the two Oki M6295 to play sample-based sounds like drums (but they are also sometimes used to play effects not music related).&lt;/li&gt;&lt;li&gt;Direct triggering of Oki M6295 samples (this is not strictly part of the state machine)&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Current simulation status is as follows:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Not done yet.&lt;/li&gt;&lt;li&gt;Partially done. The state machine works and seems to play notes at the correct speed. However, the pitch of the notes is way off.&lt;/li&gt;&lt;li&gt;Seems to be ok.&lt;/li&gt;&lt;li&gt;Is mostly ok but there are some strange things here and there - difficult to say if it's a simulation error or just how it's supposed to be.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;I am growing more and more convinced that the internal ROM of the NMK004 is the same in all games. A few of the games in the driver have additional protection issues, but at this point I don't think they are related to the NMK004.&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10457042-111012663089146037?l=mamelife.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mamelife.blogspot.com/feeds/111012663089146037/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10457042&amp;postID=111012663089146037' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/111012663089146037'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/111012663089146037'/><link rel='alternate' type='text/html' href='http://mamelife.blogspot.com/2005/03/cacophony.html' title='Cacophony'/><author><name>Nicola Salmoria</name><uri>http://www.blogger.com/profile/06048642443376701628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10457042.post-110990134875869339</id><published>2005-03-04T02:48:00.000+01:00</published><updated>2006-12-08T23:20:52.533+01:00</updated><title type='text'>Sounds Promising</title><content type='html'>It looks like the Z80 sound program for Task Force Harrier, which is the only known game predating the introductionof the NMK004, uses a data format which is very similar to the one used by the NMK004.&lt;br /&gt;&lt;br /&gt;The main command table and the sample tables are slightly different, and the music tables look very similar if not identical.&lt;br /&gt;&lt;br /&gt;It would probably be possible to modify the Z80 program to use the different tables, but I think I'll take the longer route and rewrite the program in C - so I'll learn how a program like that works in detail, which can always be useful knowledge :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10457042-110990134875869339?l=mamelife.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mamelife.blogspot.com/feeds/110990134875869339/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10457042&amp;postID=110990134875869339' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/110990134875869339'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/110990134875869339'/><link rel='alternate' type='text/html' href='http://mamelife.blogspot.com/2005/03/sounds-promising.html' title='Sounds Promising'/><author><name>Nicola Salmoria</name><uri>http://www.blogger.com/profile/06048642443376701628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10457042.post-110984117766916946</id><published>2005-03-03T09:56:00.000+01:00</published><updated>2006-12-08T23:20:48.170+01:00</updated><title type='text'>NMK Sound</title><content type='html'>One of the longest standing hurdles in MAME emulation is the sound in NMK/UPL games like Mustang, Vandyke, GunNail, etc.&lt;br /&gt;&lt;br /&gt;Those games use an custom CPU, labelled "NMK004", to drive the sound. It is still not known what kind of CPU it is, what's known is that it has 8 or 16kB of internal ROM which cannot be directly dumped, and which contains the whole program. The external ROM only contains data.&lt;br /&gt;&lt;br /&gt;I am convinced that that the program contained inside the NMK004 is either always the same, or it has minor difference to handle protection - but the format of the data in the external ROM is always the same.&lt;br /&gt;&lt;br /&gt;What I'm trying to do at the moment is understand the format of the external data. I have started with the easy part, that is the Oki 6295 samples control. I have found the command table, and the mappingd from command to 6295 sample number. This allowed me to make the games play the correct samples at the correct time so e.g. in Vandyke I hear a "swoosh" when I swing the sword and a "uumph" when I jump. I still haven't understood all of the control bits, so it isn't perfect yet, but it's a good start for a night's work.&lt;br /&gt;&lt;br /&gt;I'm hoping that other games that use a standard Z80 instead of the NMK004 will use similar logic to drive the sound (though I have already verified that they don't use the same data format as the NMK004).&lt;br /&gt;&lt;br /&gt;Of course the YM2203 part will be much harder since it won't be just a matter of playinga few samples here and there, but I will have to fully understand how the data translates into music and drive the YM2203 accordingly. However there's nothing stopping it in principle, so I am confident that eventually I or someone else will be able to add full sound to these games.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10457042-110984117766916946?l=mamelife.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mamelife.blogspot.com/feeds/110984117766916946/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10457042&amp;postID=110984117766916946' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/110984117766916946'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/110984117766916946'/><link rel='alternate' type='text/html' href='http://mamelife.blogspot.com/2005/03/nmk-sound.html' title='NMK Sound'/><author><name>Nicola Salmoria</name><uri>http://www.blogger.com/profile/06048642443376701628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10457042.post-110937313516167214</id><published>2005-02-26T00:11:00.000+01:00</published><updated>2006-12-08T23:20:44.410+01:00</updated><title type='text'>Child's Play</title><content type='html'>Well not exactly, but with the knowledge gained working on the other games decrypting Raiden Fighters Jet wasn't too hard.&lt;br /&gt;&lt;br /&gt;&lt;img title="Raiden Fighters Jet" src="http://xoomer.virgilio.it/nicola.salmoria/rfjet_3.png" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;img title="Raiden Fighters Jet" src="http://xoomer.virgilio.it/nicola.salmoria/rfjet_4.png" /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10457042-110937313516167214?l=mamelife.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mamelife.blogspot.com/feeds/110937313516167214/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10457042&amp;postID=110937313516167214' title='42 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/110937313516167214'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/110937313516167214'/><link rel='alternate' type='text/html' href='http://mamelife.blogspot.com/2005/02/childs-play.html' title='Child&apos;s Play'/><author><name>Nicola Salmoria</name><uri>http://www.blogger.com/profile/06048642443376701628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>42</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10457042.post-110927899421392671</id><published>2005-02-24T22:00:00.000+01:00</published><updated>2006-12-08T23:20:40.690+01:00</updated><title type='text'>Done</title><content type='html'>Finished decrypting the sprites in Senkyu, E-Jan High Scool, Raiden Fighters and Viper Phase 1.&lt;br /&gt;&lt;br /&gt;Raiden Fighters Jet is the only one left. It uses a different encryption, which might be similar to the one used by Raiden Fighters 2 2000.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;img title="Senkyu" src="http://xoomer.virgilio.it/nicola.salmoria/senkyu_2.png" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;img title="Raiden Fighters" src="http://xoomer.virgilio.it/nicola.salmoria/rdft_1.png" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;img title="Raiden Fighters" src="http://xoomer.virgilio.it/nicola.salmoria/rdft_2.png" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;img title="Viper Phase 1" src="http://xoomer.virgilio.it/nicola.salmoria/viper_1.png" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;img title="Viper Phase 1" src="http://xoomer.virgilio.it/nicola.salmoria/viper_2.png" /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10457042-110927899421392671?l=mamelife.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mamelife.blogspot.com/feeds/110927899421392671/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10457042&amp;postID=110927899421392671' title='45 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/110927899421392671'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/110927899421392671'/><link rel='alternate' type='text/html' href='http://mamelife.blogspot.com/2005/02/done.html' title='Done'/><author><name>Nicola Salmoria</name><uri>http://www.blogger.com/profile/06048642443376701628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>45</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10457042.post-110920266575352492</id><published>2005-02-24T00:48:00.000+01:00</published><updated>2006-12-08T23:20:35.990+01:00</updated><title type='text'>Almost Done</title><content type='html'>Things are beginning to look pretty good.&lt;br /&gt;I still have many things to fix, especially for sprites with (tileno&amp;amp;0x4000) , but most of the work is done now.&lt;br /&gt;&lt;br /&gt;&lt;img title="E-Jan High School" src="http://xoomer.virgilio.it/nicola.salmoria/ejanhs_2.png" /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10457042-110920266575352492?l=mamelife.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mamelife.blogspot.com/feeds/110920266575352492/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10457042&amp;postID=110920266575352492' title='17 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/110920266575352492'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/110920266575352492'/><link rel='alternate' type='text/html' href='http://mamelife.blogspot.com/2005/02/almost-done.html' title='Almost Done'/><author><name>Nicola Salmoria</name><uri>http://www.blogger.com/profile/06048642443376701628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>17</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10457042.post-110911734476260541</id><published>2005-02-23T01:03:00.000+01:00</published><updated>2006-12-08T23:20:31.810+01:00</updated><title type='text'>Getting There</title><content type='html'>I made a breakthrough yesterday night and could fill most of the gaps.&lt;br /&gt;&lt;br /&gt;There is still a lot to do. Part of it is simple and just requires trying various combinations until the correct one is found; I should be able to do it the next night I dedicate to the encryption. The rest is less simple and requires finding the remaining (and therefore less obvious) correlations between bits. However, the closer I get to the goal, the easier it is to see if a certain formula is correct or not.&lt;br /&gt;&lt;br /&gt;Sprites are finally good enough to show a screen shot.&lt;br /&gt;&lt;br /&gt;&lt;img title="Senkyu title screen" src="http://xoomer.virgilio.it/nicola.salmoria/senkyu.png" /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10457042-110911734476260541?l=mamelife.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mamelife.blogspot.com/feeds/110911734476260541/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10457042&amp;postID=110911734476260541' title='17 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/110911734476260541'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/110911734476260541'/><link rel='alternate' type='text/html' href='http://mamelife.blogspot.com/2005/02/getting-there.html' title='Getting There'/><author><name>Nicola Salmoria</name><uri>http://www.blogger.com/profile/06048642443376701628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>17</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10457042.post-110886621470120614</id><published>2005-02-20T03:16:00.000+01:00</published><updated>2006-12-08T23:20:28.216+01:00</updated><title type='text'>13 1/2 done, 34 1/2 to go</title><content type='html'>That's a strange way to report progress but it's the number of bits in SPI sprites that should be correctly decrypted at the moment. The encryption works on 48 bits at a time, and I have to decrypt each one of them.&lt;br /&gt;&lt;br /&gt;Luckily, having decrypted Raiden Fighters 2 makes things easier because the first few sprites in Raiden Fighters are identical, so I can compare them and see where pixels should go. However, the process isn't easy because the SPI sprite encryption is quite more complex than the tile encryption. Of the 34 1/2 bits still left to do, 16 will be particularly hard because the encryption scrambles them more aggressively. The others shouldn't be too hard to do, given enough time and patience. I have plenty of the latter, but never enough of the former.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10457042-110886621470120614?l=mamelife.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mamelife.blogspot.com/feeds/110886621470120614/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10457042&amp;postID=110886621470120614' title='18 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/110886621470120614'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/110886621470120614'/><link rel='alternate' type='text/html' href='http://mamelife.blogspot.com/2005/02/13-12-done-34-12-to-go.html' title='13 1/2 done, 34 1/2 to go'/><author><name>Nicola Salmoria</name><uri>http://www.blogger.com/profile/06048642443376701628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>18</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10457042.post-110832743188417352</id><published>2005-02-13T21:39:00.000+01:00</published><updated>2006-12-08T23:20:24.420+01:00</updated><title type='text'>First results</title><content type='html'>Decrypting the sprites was easier than expected. I've done Raiden Fighters 2 for now, which is the first game to have completely decrypted graphics. I still have to do Raiden Figthters Jet and the SPI - I don't yet know if the encryption will be similar.&lt;br /&gt;&lt;br /&gt;&lt;img title="Raiden Fighters 2" src="http://xoomer.virgilio.it/nicola.salmoria/rf2_full.png" /&gt;&lt;br /&gt;&lt;br /&gt;The game looks good now, though there are still some graphics issues - most notably priority and alpha blending. I will probably not look at those when I've finished with the decryption, leaving to someone else to finish the driver.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10457042-110832743188417352?l=mamelife.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mamelife.blogspot.com/feeds/110832743188417352/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10457042&amp;postID=110832743188417352' title='48 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/110832743188417352'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/110832743188417352'/><link rel='alternate' type='text/html' href='http://mamelife.blogspot.com/2005/02/first-results.html' title='First results'/><author><name>Nicola Salmoria</name><uri>http://www.blogger.com/profile/06048642443376701628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>48</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10457042.post-110824010831313686</id><published>2005-02-12T21:24:00.000+01:00</published><updated>2006-12-08T23:20:20.196+01:00</updated><title type='text'>And now comes the hard part</title><content type='html'>Fixing the tile banking was easy, so now I can't postpone any longer the attack to the sprite encryption.&lt;br /&gt;That should be significantly harder to fix than the tile encryption, I haven't even looked at the current algorithm yet so I haven't devised a strategy.&lt;br /&gt;&lt;br /&gt;&lt;img title="Raiden Fighters Jet" src="http://xoomer.virgilio.it/nicola.salmoria/rfjet_2.png" /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10457042-110824010831313686?l=mamelife.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mamelife.blogspot.com/feeds/110824010831313686/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10457042&amp;postID=110824010831313686' title='18 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/110824010831313686'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/110824010831313686'/><link rel='alternate' type='text/html' href='http://mamelife.blogspot.com/2005/02/and-now-comes-hard-part.html' title='And now comes the hard part'/><author><name>Nicola Salmoria</name><uri>http://www.blogger.com/profile/06048642443376701628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>18</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10457042.post-110821937569543630</id><published>2005-02-12T15:36:00.000+01:00</published><updated>2006-12-08T23:20:16.046+01:00</updated><title type='text'>All RISE!</title><content type='html'>On one side, decrypting the tiles of the RISE11 chip used by Raiden Fighters Jet was easier than I thought: after placing a few bits of the source data, it became apparent that the bit order was the same as the RISE10 chip used by Raiden Fighters 2.&lt;br /&gt;&lt;br /&gt;On the other side, however, it wasn't that easy because a couple of pixel didn't want to decrypt correctly. Eventually, it turned out to be a carry that wraps around from bit 23 to bit 0. Nasty!&lt;br /&gt;&lt;br /&gt;&lt;img title="Raiden Fighters Jet" src="http://xoomer.virgilio.it/nicola.salmoria/rfjet.png" /&gt;&lt;br /&gt;&lt;br /&gt;So I have finished decrypting the tile graphics in all Seibu games. What I will have to do next is fix how the tiles are rendered on the screen in the RISE games, because currently the tilemap layers show garbage most of the time. The above shot is pretty much the only place without graphics errors (caused either by tile banking, or sprite encryption).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10457042-110821937569543630?l=mamelife.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mamelife.blogspot.com/feeds/110821937569543630/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10457042&amp;postID=110821937569543630' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/110821937569543630'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/110821937569543630'/><link rel='alternate' type='text/html' href='http://mamelife.blogspot.com/2005/02/all-rise.html' title='All RISE!'/><author><name>Nicola Salmoria</name><uri>http://www.blogger.com/profile/06048642443376701628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10457042.post-110811498464210092</id><published>2005-02-11T09:56:00.000+01:00</published><updated>2006-12-08T23:20:11.536+01:00</updated><title type='text'>Autopilot</title><content type='html'>It's true that sometimes when you are blocked on a problem you just have to leave it aside for a while to look at it from a new perspective.&lt;br /&gt;&lt;br /&gt;Yesterday I spent much of the night fixing the tile decryption for the RISE10 chip, which is used by Raiden Fighters 2. With the experience gained on the earlier version of the chip this was much easier, and I could fix most of the problems reasonably quickly. However, there was one bit in one layer that just didn't want to work.&lt;br /&gt;&lt;br /&gt;The algorithm, now that it's understood, is really clean and simple, following intuitive patterns, but that bit didn't fit - to partially decrypt it, I had to use the wrong bits from the tile code, and pick a carry from the wrong bit of the encrypted data. It just didn't make sense.&lt;br /&gt;&lt;br /&gt;I decided to leave it alone for the night, but literally a few seconds after turning off the monitor and going to bed, the obvious answer came to me: that bit had to belong to a different plane! I must have been fetching the encrypted data from the wrong place. And indeed, this morning I checked, and bit 16 of the source data was used twice, while bit 15 was not used at all. Fixing that was all that was needed to completely fix the tile graphics.&lt;br /&gt;&lt;br /&gt;&lt;img title="Raiden Fighters 2 2000 after the fixes" src="http://xoomer.virgilio.it/nicola.salmoria/rf2_2k_after.png" /&gt;&lt;br /&gt;&lt;br /&gt;There aren't many screenshots that I can take because the driver also has problems selecting the tile bank (this is an emulation problem not related to the encryption). Plus of course, sprites are still not decrypted correctly.&lt;br /&gt;&lt;br /&gt;I still have to decide what to do next - I could either look at the RISE11 encryption, used by Raiden Fighters Jet, which will be a bit more work than the others because the current driver only decrypts two of the six planes (for the other games, the decryption was already very close). However, now that I have a good understanding of the algorithm it shouldn't take long to do it, even starting from scratch.&lt;br /&gt;&lt;br /&gt;The other thing I could do is fix the tile banking problems in Raiden Fighters 2. I haven't looked at the driver yet, it might be something simple.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10457042-110811498464210092?l=mamelife.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mamelife.blogspot.com/feeds/110811498464210092/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10457042&amp;postID=110811498464210092' title='25 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/110811498464210092'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/110811498464210092'/><link rel='alternate' type='text/html' href='http://mamelife.blogspot.com/2005/02/autopilot.html' title='Autopilot'/><author><name>Nicola Salmoria</name><uri>http://www.blogger.com/profile/06048642443376701628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>25</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10457042.post-110797386584492423</id><published>2005-02-09T19:25:00.000+01:00</published><updated>2006-12-08T23:20:08.693+01:00</updated><title type='text'>SPI progress</title><content type='html'>I started from the part that was in the best shape, the first version of the tilemap layers, and fixed the decryption errors.&lt;br /&gt;&lt;br /&gt;&lt;img title="E-Jan High School after the fixes" src="http://xoomer.virgilio.it/nicola.salmoria/ejanhs_after.png" /&gt;&lt;br /&gt;&lt;br /&gt;This encryption is used by Senkyu, E-Jan High School, Viper Phase 1 and Raiden Fighters. I will look at the other versions of the tile encryption next. Sprites are harder to do and will be done last.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10457042-110797386584492423?l=mamelife.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mamelife.blogspot.com/feeds/110797386584492423/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10457042&amp;postID=110797386584492423' title='18 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/110797386584492423'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/110797386584492423'/><link rel='alternate' type='text/html' href='http://mamelife.blogspot.com/2005/02/spi-progress.html' title='SPI progress'/><author><name>Nicola Salmoria</name><uri>http://www.blogger.com/profile/06048642443376701628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>18</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10457042.post-110782759195034756</id><published>2005-02-08T02:41:00.000+01:00</published><updated>2006-12-08T23:20:05.240+01:00</updated><title type='text'>Seibu SPI encryption</title><content type='html'>I'm looking at the Seibu SPI graphics encryption at the moment. For now, I'm fixing the small mistakes in the tilemap layers of Senkyu etc., after that I might look at the sprites as well.&lt;br /&gt;&lt;br /&gt;Most of the work has already been done on the tilemap layer, but there are some mistakes. I have understood while they are happening and already fixed one of them. It's clear how the algorithm works, it's a bitswap + arithmetic calculations (additions instead of simple XORs - this is not common). Replacing the lookup table with formulas and fixing the remaining bugs is just a matter of time and patience at this point.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10457042-110782759195034756?l=mamelife.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mamelife.blogspot.com/feeds/110782759195034756/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10457042&amp;postID=110782759195034756' title='18 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/110782759195034756'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/110782759195034756'/><link rel='alternate' type='text/html' href='http://mamelife.blogspot.com/2005/02/seibu-spi-encryption.html' title='Seibu SPI encryption'/><author><name>Nicola Salmoria</name><uri>http://www.blogger.com/profile/06048642443376701628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>18</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10457042.post-110769112318378194</id><published>2005-02-06T13:27:00.000+01:00</published><updated>2006-12-08T23:20:01.130+01:00</updated><title type='text'>F3 sound</title><content type='html'>The issues with F3 sound were intriguing.&lt;br /&gt;These games all use essentially the same sound program, with minor variations, which appears to be a generic MIDI player.&lt;br /&gt;&lt;br /&gt;The hardware is capable of driving a large amount of ROM data - more than the ES5505 is capable of, so the ROMs are banked, in 4 or 8 banks depending on the player version. The ROMs are actually half the amount of banks, because every ROM contains two banks (apart a couple of exception games that use smaller ROMs).&lt;br /&gt;&lt;br /&gt;At the beginning of each bank, the ROMs contain a standard header that the program reads on startup to see what samples are available. Therefore, the order how the ROMs are loaded isn't strict - if you swap two of them, the program will still know which one is which and play the correct samples anyway.&lt;br /&gt;&lt;br /&gt;However, there's a catch. Most of the games have one ROM containing standard samples (the same in all the games that have them) and those samples are stored differently from the others (there is no header), so the program cannot recognize them. The program just expects those standard samples to always be stored in the last bank.&lt;br /&gt;&lt;br /&gt;Discovering this was important to fix sound in a few games - for examples Space Invaders DX, which was missing music.&lt;br /&gt;&lt;br /&gt;However, it still wasn't enough to fix all the problems. For some reason, ROMs loaded in bank #4 were not recognized properly, so they were ignored by the program. After some studying of the ROM detection function, I finally found the not-so-obvious cause.&lt;br /&gt;&lt;br /&gt;Usually, 68000 programs have ROM starting from address 000000, because that's where the reset vector is located. This program, however, for some reason works differently, and ROM is located higher in memory while RAM is at 000000.&lt;br /&gt;The 68000 also has a special instruction to move data in its address registers, called MOVEA. It is different from MOVE because a MOVE.W will just affect the bottom 16 bits of the destination register, while MOVEA.W will sign extend the result to 32 bits. Therefore,&lt;br /&gt;MOVEA.W  #$7FFF,A0&lt;br /&gt;will put #$00007FFF in A0, while&lt;br /&gt;MoveA.W #$8000,A0&lt;br /&gt;will put #$FFFF8000 in A0.&lt;br /&gt;&lt;br /&gt;What was happening with the program was that the data read from the ROMs went to a buffer starting at around #$006000, and continuing onwards until it crossed the magic #$008000 boundary. When it did, the program would begin writing data at #$FF8000, but read it back from #$008000. This is what is called a "mirror address" - different addresses that map to the same chip on the board. The FF8000-FFFFFF area was mapped in the driver, but not as a mirror of 000000-00FFFF. Once that was fixed, the program started properly recognizing all of its ROMs.&lt;br /&gt;&lt;br /&gt;I have checked all the games, looking at the ROMs to make sure they were in the order expected by the game, and playing them to look for obvious problems, and I couldn't find any, so now all of the F3 games should be sounding pretty good.&lt;br /&gt;&lt;br /&gt;In the process, I also discovered that Quiz Theater was missing sound because of a bad ROM. I was able to partially repair it because most of the damage was in a portion which is common to other games, however there are still some parts missing so some sounds willnot play as they should. Ring Rage and Riding Fight still have no sound, however in this case I believe it's an emulation issue. Both of these games use a very old version of the sound program, possibly the earliest revision, so it might behave a little differently from the later ones.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10457042-110769112318378194?l=mamelife.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mamelife.blogspot.com/feeds/110769112318378194/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10457042&amp;postID=110769112318378194' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/110769112318378194'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/110769112318378194'/><link rel='alternate' type='text/html' href='http://mamelife.blogspot.com/2005/02/f3-sound.html' title='F3 sound'/><author><name>Nicola Salmoria</name><uri>http://www.blogger.com/profile/06048642443376701628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10457042.post-110746632880353048</id><published>2005-02-03T22:21:00.000+01:00</published><updated>2006-12-08T23:19:57.556+01:00</updated><title type='text'>Universal, part 2</title><content type='html'>But the strangest thing about Mr Do's Castle board is the third Z80. This CPU has a tiny program ROM - 256 bytes, and most of them empty. It sits there, doing almost nothing. It communicates with the main CPU using the same method described in the previous article, but it doesn't send anything back.&lt;br /&gt;The interesting thing is &lt;em&gt;what&lt;/em&gt; the main CPU sends it. It's not just 9 bytes as with the second CPU. It is 0x200 bytes, and it's the sprite data. So essentially what the third CPU does is sit there, wait for the sprite data from the main CPU, and pass it over to the video hardware.&lt;br /&gt;Why couldn't the main CPU just send the data to the video hardware by itself? That's the difficult question. I haven't an answer yet.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10457042-110746632880353048?l=mamelife.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mamelife.blogspot.com/feeds/110746632880353048/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10457042&amp;postID=110746632880353048' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/110746632880353048'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/110746632880353048'/><link rel='alternate' type='text/html' href='http://mamelife.blogspot.com/2005/02/universal-part-2.html' title='Universal, part 2'/><author><name>Nicola Salmoria</name><uri>http://www.blogger.com/profile/06048642443376701628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10457042.post-110745023863386352</id><published>2005-02-03T09:44:00.000+01:00</published><updated>2006-12-08T23:19:53.833+01:00</updated><title type='text'>Universal</title><content type='html'>Universal, best known for their Mr. Do! series, surely made original games. Their hardware isn't less original; it's actually one of the more unique and strangest ones in MAME. A lot of things in their boards were done differently from everyone else, and in non-obvious ways.&lt;br /&gt;Even the style of the schematics drawings is unique and instantly recognizable - albeit not the easist to follow.&lt;br /&gt;&lt;br /&gt;There is a long standing problem with the games Mr. Do's Castle and Do! Run Run, where the dip switch settings are not read by the game. The problem has been reported to happen even on real boards, so it is probably a timing issue (small deviations from the nominal rates of the components could throw the timing off enough to break it). For now, we'll fix it in MAME by just changing the CPU clock rate by a small amount. Kind of black magic, but it works.&lt;br /&gt;&lt;br /&gt;Anyway, while studying the schematics I finally understood one thing that had eluded me until now: how the CPU communication happens on the real board. The two CPUs exchange bursts of 9 bytes, but there is only a single bidirectional buffer between them. How could it possibly work? Well, the Universal designers took advantage of the Z80 WAIT input. When the main CPU reads or writes the buffer, the WAIT line is asserted, so the CPU is put on hold. When the sub CPU reads of writes the buffer, the WAIT line of the main CPU is cleared, thus making it resume execution. So when the main CPU writes to the buffer, it will put the data there and pause until the sub CPU has read it. When it reads the buffer, it will pause until the sub CPU has written data to it, and resume execution (reading that new data).&lt;br /&gt;&lt;br /&gt;Very cheap and effective. However, I wouldn't want to fly on a plane that uses this technique. :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10457042-110745023863386352?l=mamelife.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mamelife.blogspot.com/feeds/110745023863386352/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10457042&amp;postID=110745023863386352' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/110745023863386352'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/110745023863386352'/><link rel='alternate' type='text/html' href='http://mamelife.blogspot.com/2005/02/universal.html' title='Universal'/><author><name>Nicola Salmoria</name><uri>http://www.blogger.com/profile/06048642443376701628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10457042.post-110721572882418598</id><published>2005-02-01T01:47:00.000+01:00</published><updated>2006-12-08T23:19:49.483+01:00</updated><title type='text'>I wish they were all like this...</title><content type='html'>I was asked to look at the encryption of a game called Super Trio, and it tunerd out to be some very basic XOR on the bottom address lines, surely done by a PAL near the 68000.&lt;br /&gt;One wonders why did they even bother to encrypt it, if it was so trivial to break (moreover, surely a PAL based encryption would have posed no problem for any bootlegger).&lt;br /&gt;&lt;br /&gt;Anyway, I don't have time to write new drivers these days, so my job is done. Hopefully the hardware won't be difficult to figure out, so we'll soon be able to revive another nice and rare game (as I'm told).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10457042-110721572882418598?l=mamelife.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mamelife.blogspot.com/feeds/110721572882418598/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10457042&amp;postID=110721572882418598' title='11 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/110721572882418598'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/110721572882418598'/><link rel='alternate' type='text/html' href='http://mamelife.blogspot.com/2005/02/i-wish-they-were-all-like-this.html' title='I wish they were all like this...'/><author><name>Nicola Salmoria</name><uri>http://www.blogger.com/profile/06048642443376701628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>11</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10457042.post-110712651842976891</id><published>2005-01-31T01:03:00.000+01:00</published><updated>2006-12-08T23:19:46.083+01:00</updated><title type='text'>Chain reaction</title><content type='html'>It seems that whenever I look at a driver, I find something to fix in it&lt;br /&gt;In this case, while looking at TNZS, I noticed that some games, e.g. Insector X and Plump Pop, were quite obviously running at 30 fps instead of the normal 60. This makes a lot of difference in the smoothness, strange that nobody ever noticed. Anyway, this was caused by missing support for sprite banking, a feature of the hardware which was already supported by seta.c (the games running in this driver use Seta custom chips). It's now fixed so Insector X looks better than ever :) The improved emulation also fixed the various gfx issues with Kabuki Z.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10457042-110712651842976891?l=mamelife.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mamelife.blogspot.com/feeds/110712651842976891/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10457042&amp;postID=110712651842976891' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/110712651842976891'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/110712651842976891'/><link rel='alternate' type='text/html' href='http://mamelife.blogspot.com/2005/01/chain-reaction.html' title='Chain reaction'/><author><name>Nicola Salmoria</name><uri>http://www.blogger.com/profile/06048642443376701628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10457042.post-110709752129278817</id><published>2005-01-30T15:48:00.000+01:00</published><updated>2006-12-08T23:19:42.456+01:00</updated><title type='text'>Some bugs never die</title><content type='html'>Fascinating how some bugs have stayed with us for years, even if the solution was simple and obvious.&lt;br /&gt;&lt;br /&gt;There had been two bugs plaguing emulation of The New Zealand Story:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;A hanging bug, which would make the game simply stop, while music was still playing. This happened randomly at some key points, typically the end of a level when you touched the cage. This was caused by a bug in the original program (a RET NZ instead of RET Z), which would cause no apparent problem on the real hardware, but could be deadly in MAME.&lt;br /&gt;This bug had been fixed for a long time, 0.91 contains a cleaner workaround but the behaviour is the same.&lt;/li&gt;&lt;li&gt;A crashing bug, happening at different times in the three different versions of the game. For example, in the current main set, it would happen when the cannon-firing sheep was on the screen. This was caused by a known limitation in the MAME handling of banked ROM areas. It is not a big problem, and we know how to deal with it, and there was code in the driver to do that. Unfortunately, the code was copying the wrong data! It has been like this forever, and nobody ever noticed. But at last it has been discovered, so I can promise you, from 0.91u2 TNZS will no longer crash :)&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10457042-110709752129278817?l=mamelife.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mamelife.blogspot.com/feeds/110709752129278817/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10457042&amp;postID=110709752129278817' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/110709752129278817'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/110709752129278817'/><link rel='alternate' type='text/html' href='http://mamelife.blogspot.com/2005/01/some-bugs-never-die.html' title='Some bugs never die'/><author><name>Nicola Salmoria</name><uri>http://www.blogger.com/profile/06048642443376701628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10457042.post-110701493319146312</id><published>2005-01-29T16:59:00.000+01:00</published><updated>2006-12-08T23:19:38.873+01:00</updated><title type='text'>Kram is working!</title><content type='html'>I have finished the manual decryption. By that I mean that I made tables that list all addresses of encrypted instructions, and what to replace them with. The total number of entries in the tables is 7926. This is not an optimal solution but since I doubt I will manage to understand the algorithm it's the only thing I can do.&lt;br /&gt;&lt;br /&gt;An interested thing I found out when hooking up the tables in the driver is that for two-byte opcodes, only the first byte is encrypted, the second is unencrypted. This wasn't the case with the Konami-1 CPU, where both bytes are encrypted. Odd.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10457042-110701493319146312?l=mamelife.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mamelife.blogspot.com/feeds/110701493319146312/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10457042&amp;postID=110701493319146312' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/110701493319146312'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/110701493319146312'/><link rel='alternate' type='text/html' href='http://mamelife.blogspot.com/2005/01/kram-is-working.html' title='Kram is working!'/><author><name>Nicola Salmoria</name><uri>http://www.blogger.com/profile/06048642443376701628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10457042.post-110696552977918231</id><published>2005-01-29T03:18:00.000+01:00</published><updated>2006-12-08T23:19:34.936+01:00</updated><title type='text'>Reaching a brick wall</title><content type='html'>No progress on the Kram encryption algorithm. Changing even a single bit of the address changes the result in an unpredictable way. At this point I'm doubting that I'll be able to derive the algorithm.&lt;br /&gt;&lt;br /&gt;Manual decryption of the game, instead, is proceeding. I'm at about 80%, I think. The service menus are working, while the game is still booting to a black screen.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10457042-110696552977918231?l=mamelife.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mamelife.blogspot.com/feeds/110696552977918231/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10457042&amp;postID=110696552977918231' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/110696552977918231'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/110696552977918231'/><link rel='alternate' type='text/html' href='http://mamelife.blogspot.com/2005/01/reaching-brick-wall.html' title='Reaching a brick wall'/><author><name>Nicola Salmoria</name><uri>http://www.blogger.com/profile/06048642443376701628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10457042.post-110690750991018736</id><published>2005-01-28T02:53:00.000+01:00</published><updated>2006-12-08T23:19:30.960+01:00</updated><title type='text'>Kram hurdles</title><content type='html'>Looking for "good" keys didn't work, there are no bit permutations that show noticeably better applicability than others, the only thing I found is that a 0x22 final xor is significantly more common, which is good on one side, but not that good on the other side because it cannot be the ONLY xor - there must be others.&lt;br /&gt;&lt;br /&gt;The manual decryption by comparison with the other sets is almost complete, CPU #2 is 100% while CPU #1 is maybe 75%. The code is different in a few places because this version doesn't have the MCU, and actually there seems to be a large chunk of code in the encrypted version that isn't in the others, so I might not be able to do a complete decryption if I don't break the encryption algorithm.&lt;br /&gt;&lt;br /&gt;One interesting thing to note is that the code has been reassembled with a different assembler, which generates different (but equivalent) instructions in some cases. Here is an example:&lt;br /&gt;&lt;br /&gt;not encrypted version:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;D08D: CE B8 D3      LDU   #$B8D3&lt;br /&gt;D090: EC 84         LDD   ,X&lt;br /&gt;D092: 81 29         CMPA  #$29&lt;/pre&gt;encrypted version:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;D082: CE B8 D3      LDU   #$B8D3&lt;br /&gt;D085: EC 00         LDD $0000,X&lt;br /&gt;D087: 81 29         CMPA #$29&lt;/pre&gt;the middle instruction does the same thing but with a different opcode.&lt;br /&gt;&lt;br /&gt;Yesterday I verified that bytes at the same address are decrypted in the same way, and that in that case changing one bit in the encrypted value changes one bit in the decrypted value. Tomorrow I will try pairs of addresses only differing by one bit, and see if there is a similar regularity. From what I could see, however, I'm not very optimistic.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10457042-110690750991018736?l=mamelife.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mamelife.blogspot.com/feeds/110690750991018736/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10457042&amp;postID=110690750991018736' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/110690750991018736'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/110690750991018736'/><link rel='alternate' type='text/html' href='http://mamelife.blogspot.com/2005/01/kram-hurdles.html' title='Kram hurdles'/><author><name>Nicola Salmoria</name><uri>http://www.blogger.com/profile/06048642443376701628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10457042.post-110690725993527905</id><published>2005-01-26T10:31:00.000+01:00</published><updated>2006-12-08T23:19:27.083+01:00</updated><title type='text'>Kram progress</title><content type='html'>My intuition was right: the two Kram CPUs use the same encryption. Every time there is the same encrypted value at the same address in the two CPUs, it decrypts to the same value.&lt;br&gt;&lt;br /&gt;Not only that but, at a given address,&amp;nbsp;if N bits change in the encrypted value, then N bits change in the decrypted value. This proves that the encryption consists of a bitswap and a xor.&lt;br&gt;&lt;br /&gt;&lt;BR&gt;That was the good news. The bad news is that the encryption changes with the address, and there isn't much data to analyze. For most addresses I have only one encrypted-decrypted pair, for a few I have two. There is no way to obtain more than what I have without physical access to the CPU.&lt;br&gt;&lt;br /&gt;&lt;BR&gt;Of course, since for now we have to assume that the encryption consists of a free bitswap + free xor, this means that given a single pair it could be decrypted correctly with any of 8! = 8*7*6*5*4*3*2*1 = 40320 different keys: just pick any of the 8! possible permutations of the bits, and then select the 8-bit xor that fixes the result.&lt;br&gt;&lt;br /&gt;&lt;BR&gt;What I need to do now is try to figure out the relation between address and key, which isn't obvious at the moment.&amp;nbsp;The total possible keys are 8! * 2^8 = 10321920, which isn't too much. What I plan to do is check how many values are decrypted correctly by each one of them (or better, by a subset of them). If we are lucky, some keys will show a significantly better success rate, meaning they are "good" ones. If we are not lucky, it will mean that bitswap and xor are independently affected by the address.&lt;br&gt;&lt;br /&gt;&lt;BR&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10457042-110690725993527905?l=mamelife.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mamelife.blogspot.com/feeds/110690725993527905/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10457042&amp;postID=110690725993527905' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/110690725993527905'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/110690725993527905'/><link rel='alternate' type='text/html' href='http://mamelife.blogspot.com/2005/01/kram-progress.html' title='Kram progress'/><author><name>Nicola Salmoria</name><uri>http://www.blogger.com/profile/06048642443376701628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10457042.post-110690721082123236</id><published>2005-01-26T10:00:00.000+01:00</published><updated>2006-12-08T23:19:23.376+01:00</updated><title type='text'>Kram encryption</title><content type='html'>And of course, another still unsolved issue with the Qix driver is the encrypted version of Kram.&lt;br&gt;&lt;br /&gt;&lt;BR&gt;This is unusual because it's possibly the only time that Taito used encryption instead of MCU protection (off the top of my head, I can't think of any other encrypted Taito game). It is also a rare example of an encrypted 6809 game - again, the only other 6809 encrypted games that come to mind are the ones using the Konami-1 CPU.&lt;br&gt;&lt;br /&gt;&lt;BR&gt;I had looked at this encryption other times in the past, with no success. There probably isn't enough data to figure it out, but comparison with the other version of Kram will at least be enough to decrypt it, even if it will mean using a large hardcoded table - and who knows, in the process I might discover something new.&lt;br&gt;&lt;br /&gt;&lt;BR&gt;The encryption only works on opcodes, leaving data decrypted, which is good because you can easily align code from the encrypted and unencrypted versions of the game. Unlike the 68000, where everything that is fetched in the process of executing an instruction (plus PC-relative indirect memory accesess) is considered program space, and only memory accesses caused by an instuuction are considered data space, in the 6809 only the first byte of an instruction (the opcode itself) is encrypted, while the other bytes of a multibyte instruction are left unencrypted. This means that when comparing encrypted and decrypted blocks of code you have plenty of reference to align them perfectly.&lt;br&gt;&lt;br /&gt;&lt;BR&gt;The encrypted version of Kram should actually be almost identical to the other two, minus the MCU handling which isn't present in that version since it was protected in another way (Sega, anyone?). I should be able to do most of the decryption automatically and fill a couple of holes manually in the places that are different. Since both 6809 are encrypted, my hope is that they use the same encryption, so I might discover something more about it by comparing encrypted bytes at the same address on the two CPUs.&lt;BR&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10457042-110690721082123236?l=mamelife.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mamelife.blogspot.com/feeds/110690721082123236/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10457042&amp;postID=110690721082123236' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/110690721082123236'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/110690721082123236'/><link rel='alternate' type='text/html' href='http://mamelife.blogspot.com/2005/01/kram-encryption.html' title='Kram encryption'/><author><name>Nicola Salmoria</name><uri>http://www.blogger.com/profile/06048642443376701628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10457042.post-110690715286976277</id><published>2005-01-26T01:43:00.000+01:00</published><updated>2006-12-08T23:19:19.066+01:00</updated><title type='text'>Fix one thing, discover another</title><content type='html'>Electric Yo-Yo was easy to fix, it was crashing because of a synchronization issue between the two CPUs - increasing interleaving fixed the problem.&lt;br&gt;&lt;br /&gt;&lt;BR&gt;Looking at the schematics surely was interesting, for example I discovered that the video ROM bank&amp;nbsp;latch (which is a late&amp;nbsp;addition only present in Zookeeper) is mapped on a mirror address of the diagnostic LED / palette bank latch. This explains why they oddly mapped the ROM banking bit on data bit 2, instead of the more obvious bit 0. That's because bits 0 and 1 are the ones that control the palette bank, and since the ROM bank latch is at a mirror address of the palette bank latch, whenver the former is written to, the latter is affected as well. So whenever the game wants to set the ROM bank, it also copies the palette bank in bits 0 and 1 to avoid unwanted side effects.&lt;BR&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10457042-110690715286976277?l=mamelife.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mamelife.blogspot.com/feeds/110690715286976277/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10457042&amp;postID=110690715286976277' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/110690715286976277'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/110690715286976277'/><link rel='alternate' type='text/html' href='http://mamelife.blogspot.com/2005/01/fix-one-thing-discover-another.html' title='Fix one thing, discover another'/><author><name>Nicola Salmoria</name><uri>http://www.blogger.com/profile/06048642443376701628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10457042.post-110690515437205675</id><published>2005-01-25T09:25:00.000+01:00</published><updated>2006-12-08T23:17:16.680+01:00</updated><title type='text'>Memories...</title><content type='html'>I'm looking at the good old Qix driver at the moment. This was one of the first drivers in MAME, and at the time it seemed really complex, with its three CPUs and the need to synchronize them with a certain degree of accuracy.&lt;br /&gt;&lt;br /&gt;The driver is already very well written and documented, but I'm checking the schematics again to verify that everything is correct, then I'll try to fix the Electric Yo-Yo hang during attract mode.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10457042-110690515437205675?l=mamelife.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mamelife.blogspot.com/feeds/110690515437205675/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10457042&amp;postID=110690515437205675' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/110690515437205675'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10457042/posts/default/110690515437205675'/><link rel='alternate' type='text/html' href='http://mamelife.blogspot.com/2005/01/memories.html' title='Memories...'/><author><name>Nicola Salmoria</name><uri>http://www.blogger.com/profile/06048642443376701628</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
