| 1 | (Please bear with me: I can't use any periods or commas or
|
|---|
| 2 | hyphens in this introduction)
|
|---|
| 3 |
|
|---|
| 4 | This is an implementation of CSS decryption in the Brainfuck
|
|---|
| 5 | programming language
|
|---|
| 6 |
|
|---|
| 7 | It consumes exactly 2053 bytes of input and produces exactly
|
|---|
| 8 | 2048 bytes of output: the input is the five byte title key
|
|---|
| 9 | followed by a 2048 byte sector to decrypt and the output is
|
|---|
| 10 | the decrypted sector (or the original sector if it wasn't
|
|---|
| 11 | encrypted)
|
|---|
| 12 |
|
|---|
| 13 | You can't decrypt more than one sector at a time because BF
|
|---|
| 14 | doesn't provide any way to detect the end of the input;
|
|---|
| 15 | rather than make an infinite loop I decided to stop after
|
|---|
| 16 | one iteration
|
|---|
| 17 |
|
|---|
| 18 | CSS is the encryption used on DVDs and Brainfuck is a Turing
|
|---|
| 19 | complete programming language which actually resembles a
|
|---|
| 20 | Turing machine to no small degree: in particular it uses a
|
|---|
| 21 | linear workspace accessed through a "read/write head" which
|
|---|
| 22 | can only move by one cell at a time
|
|---|
| 23 |
|
|---|
| 24 | It's a lot of fun to watch this program in action if you
|
|---|
| 25 | have a BF interpreter which shows the movement of the head
|
|---|
| 26 | (and if you don't have one write one: it takes about five
|
|---|
| 27 | minutes)
|
|---|
| 28 |
|
|---|
| 29 | Now on with the show
|
|---|
| 30 |
|
|---|
| 31 | ____________________________________________________________
|
|---|
| 32 |
|
|---|
| 33 |
|
|---|
| 34 | read the key
|
|---|
| 35 | ,>,>,>,>,>
|
|---|
| 36 |
|
|---|
| 37 | copy the first 21 bytes of the sector unchanged
|
|---|
| 38 | +++[->+++++++[->,.<]<]
|
|---|
| 39 |
|
|---|
| 40 | convert the 21st byte to binary
|
|---|
| 41 | >>[->>[>]+<[-<]<]
|
|---|
| 42 |
|
|---|
| 43 | save bit 4 (the encryption bit); nuke the rest
|
|---|
| 44 | >>[-]>[-]>[-]>[-]>[-<<<<<<<+>>>>>>>]>[-]>[-]>[-]<<<<<<<<<<
|
|---|
| 45 |
|
|---|
| 46 | if it's set:
|
|---|
| 47 | <+>[-
|
|---|
| 48 |
|
|---|
| 49 | copy another 64 bytes
|
|---|
| 50 | <+++++++[->++++++++[->,.<]<]
|
|---|
| 51 |
|
|---|
| 52 | xor the most recent byte from input with the first key byte
|
|---|
| 53 | <<<<<[->>>>>>+<<<<<<]>>>>>>
|
|---|
| 54 | [->>>>[>>]+<<[-<<]<<]>
|
|---|
| 55 | [->>>>[>>]+<<[-<<]<<]>
|
|---|
| 56 | >>[>[-<->]<[->+<]]>>[>[-<->]<[->+<]]
|
|---|
| 57 | >>[>[-<->]<[->+<]]>>[>[-<->]<[->+<]]
|
|---|
| 58 | >>[>[-<->]<[->+<]]>>[>[-<->]<[->+<]]
|
|---|
| 59 | >>[>[-<->]<[->+<]]>>[>[-<->]<[->+<]]
|
|---|
| 60 |
|
|---|
| 61 | fill in the always set bits in the LFSRs
|
|---|
| 62 | >>>>>>>>>>+>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<
|
|---|
| 63 |
|
|---|
| 64 | move the xor'ed byte to its final location (in the 17 bit LFSR)
|
|---|
| 65 | <[->>>>>>>>+<<<<<<<<]<
|
|---|
| 66 | <[->>>>>>>>>+<<<<<<<<<]<
|
|---|
| 67 | <[->>>>>>>>>>+<<<<<<<<<<]<
|
|---|
| 68 | <[->>>>>>>>>>>+<<<<<<<<<<<]<
|
|---|
| 69 | <[->>>>>>>>>>>>+<<<<<<<<<<<<]<
|
|---|
| 70 | <[->>>>>>>>>>>>>+<<<<<<<<<<<<<]<
|
|---|
| 71 | <[->>>>>>>>>>>>>>+<<<<<<<<<<<<<<]<
|
|---|
| 72 | <[->>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<]<
|
|---|
| 73 |
|
|---|
| 74 | same thing for the next four bytes (yuck)
|
|---|
| 75 | <<<<<<<<<[->>>>>+<<<<<]>>>>>>,.<
|
|---|
| 76 | [->>>>[>>]+<<[-<<]<<]>[->>>>[>>]+<<[-<<]<<]>
|
|---|
| 77 | >>[>[-<->]<[->+<]]>>[>[-<->]<[->+<]]
|
|---|
| 78 | >>[>[-<->]<[->+<]]>>[>[-<->]<[->+<]]
|
|---|
| 79 | >>[>[-<->]<[->+<]]>>[>[-<->]<[->+<]]
|
|---|
| 80 | >>[>[-<->]<[->+<]]>>[>[-<->]<[->+<]]
|
|---|
| 81 | >[->>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<]<
|
|---|
| 82 | <[->>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<]<
|
|---|
| 83 | <[->>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<]<
|
|---|
| 84 | <[->>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<]<
|
|---|
| 85 | <[->>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<]<
|
|---|
| 86 | <[->>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<]<
|
|---|
| 87 | <[->>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<]<
|
|---|
| 88 | <[->>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<]<
|
|---|
| 89 | <<<<<<<<[->>>>+<<<<]>>>>>,.<
|
|---|
| 90 | [->>>>[>>]+<<[-<<]<<]>[->>>>[>>]+<<[-<<]<<]>
|
|---|
| 91 | >>[>[-<->]<[->+<]]>>[>[-<->]<[->+<]]>>[>[-<->]<[->+<]]>>[>[-<->]<[->+<]]
|
|---|
| 92 | >>[>[-<->]<[->+<]]>>[>[-<->]<[->+<]]>>[>[-<->]<[->+<]]>>[>[-<->]<[->+<]]
|
|---|
| 93 | >[->>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<]<
|
|---|
| 94 | <[->>>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<]<
|
|---|
| 95 | <[->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<]<
|
|---|
| 96 | <[->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<]<
|
|---|
| 97 | <[->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<]<
|
|---|
| 98 | <[->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<]<
|
|---|
| 99 | <[->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<]<
|
|---|
| 100 | <[->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<]<
|
|---|
| 101 | <<<<<<<[->>>+<<<]>>>>,.<
|
|---|
| 102 | [->>>>[>>]+<<[-<<]<<]>[->>>>[>>]+<<[-<<]<<]>
|
|---|
| 103 | >>[>[-<->]<[->+<]]>>[>[-<->]<[->+<]]>>[>[-<->]<[->+<]]>>[>[-<->]<[->+<]]
|
|---|
| 104 | >>[>[-<->]<[->+<]]>>[>[-<->]<[->+<]]>>[>[-<->]<[->+<]]>>[>[-<->]<[->+<]]
|
|---|
| 105 | >[->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<]<
|
|---|
| 106 | <[->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<]<
|
|---|
| 107 | <[->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<]<
|
|---|
| 108 | <[->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<]<
|
|---|
| 109 | <[->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<]<
|
|---|
| 110 | <[->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<]<
|
|---|
| 111 | <[->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<]<
|
|---|
| 112 | <[->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<]<
|
|---|
| 113 | <<<<<<[->>+<<]>>>,.<
|
|---|
| 114 | [->>>>[>>]+<<[-<<]<<]>[->>>>[>>]+<<[-<<]<<]>
|
|---|
| 115 | >>[>[-<->]<[->+<]]>>[>[-<->]<[->+<]]>>[>[-<->]<[->+<]]
|
|---|
| 116 | >>[>[-<->]<[->+<]]>>[>[-<->]<[->+<]]>>[>[-<->]<[->+<]]>>[>[-<->]<[->+<]]>>[>[-<->]<[->+<]]
|
|---|
| 117 | >[->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<]<
|
|---|
| 118 | <[->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<]<
|
|---|
| 119 | <[->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<]<
|
|---|
| 120 | <[->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<]<
|
|---|
| 121 | <[->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<]<
|
|---|
| 122 | <[->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<]<
|
|---|
| 123 | <[->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<]<
|
|---|
| 124 | <[->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<]<
|
|---|
| 125 |
|
|---|
| 126 | <<<<<<<<
|
|---|
| 127 |
|
|---|
| 128 | copy the remaining 39 bytes of the header
|
|---|
| 129 | +++[->+++++++++++++[->,.<]<] <<
|
|---|
| 130 |
|
|---|
| 131 | main decryption loop: for each of 1920 bytes:
|
|---|
| 132 | +++++[->++++++[->++++++++[->++++++++[->
|
|---|
| 133 |
|
|---|
| 134 | read a byte and convert it to binary
|
|---|
| 135 | ,[->>>[>>]+<<[-<<]<]
|
|---|
| 136 |
|
|---|
| 137 | perform the mangling step (bit ordering is AaBbCcDdEeFfGgHh)
|
|---|
| 138 | >>>>>>+>>+>>>>+>>>>+>
|
|---|
| 139 | [-<<<<<->>>>>] <<[-<<<<<<<<<<<+>>>>>>>>>>>] F =!h; B = g;
|
|---|
| 140 | ++<<[->>->>+<<<<<<<<<<<->>>>>>>]<< [->>>>->>+<-<<<<<]<< C =!f; H =!e; g=2 minus e minus f; h=e plus f
|
|---|
| 141 | [-<<<<<<<+>>>>>>>]<< [->>>+<<<] A = d; E = c;
|
|---|
| 142 | ++<<[->>->-<<<]<< [->>>>->>>>>>>+<<<<<<<<<<<] D =!b; G = a; c=2 minus a minus b;
|
|---|
| 143 | >>>>[[-]<<<<+<[->-<]>[-<+>]>>>>>>+>[-<->]<[->+<]<<] A ^=!!c; E ^=!!c; (!!c == !(a&b))
|
|---|
| 144 | >>>>>>>>[[-]<<<<<<<<<<+<[->-<]>[-<+>]>>>>>>>>>>] B ^=!!g; (!!g == !(e&f))
|
|---|
| 145 | >>[[-]<<<<+<[->-<]>[-<+>]>>>>]<<<<<<<<<<<<<<< F ^=!!h; (!!h == (e|f))
|
|---|
| 146 | [->>[->+>[-<->]<[->+<]>>+>[-<->]<[->+<]<<+<]>[-<+>]<<+<]>[-<+>] C ^= A&B; D ^= A&B;
|
|---|
| 147 | >>>>>>>>>>++<<<[->+>>->>+<<<<<]>[-<+>]>[-<+>>->>+<<<]<[->+<] f = 2 minus E minus F; g = E plus F;
|
|---|
| 148 | >>[[-]+>[-<->]<[->+<]]>>[[-]+>[-<->]<[->+<]] G ^=!!f; H ^=!!g;
|
|---|
| 149 |
|
|---|
| 150 | generate eight cipher bits
|
|---|
| 151 | >>++++++++[>
|
|---|
| 152 |
|
|---|
| 153 | clock the 17 bit LFSR and add end bit to previous carry
|
|---|
| 154 | >>+>> >>>>>>>>>>>>>>>>
|
|---|
| 155 | [-<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>]<
|
|---|
| 156 | [->+<]<[->+<]<[->+<]<[->+<]<[->+<]<[->+<]<
|
|---|
| 157 | [->+<]<[->+<]<[->+<]<[->+<]<[->+<]<[->+<]<
|
|---|
| 158 | [->+<]<[->+<<<<+>>>]<[->+<]<[->+<]<
|
|---|
| 159 | [->+<<->[->-<<+>]]
|
|---|
| 160 |
|
|---|
| 161 | clock the 25 bit LFSR and add end bit to total
|
|---|
| 162 | >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>
|
|---|
| 163 | [-<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>]<
|
|---|
| 164 | [->+<]<[->+<]<
|
|---|
| 165 | [->+<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>]<
|
|---|
| 166 | [->+<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>]<
|
|---|
| 167 | [->+<]<[->+<]<[->+<]<[->+<]<[->+<]<[->+<]<[->+<]<
|
|---|
| 168 | [->+<<<<<<<<<<<<<<+>>>>>>>>>>>>>]<
|
|---|
| 169 | [->+<]<[->+<]<[->+<]<[->+<]<[->+<]<[->+<]<
|
|---|
| 170 | [->+<]<[->+<]<[->+<]<[->+<]<[->+<]<[->+<]<
|
|---|
| 171 | [->+<<+>[->-<<->[->+<<+>[->-<<->]]]]<
|
|---|
| 172 | [-<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>]<<<<<<<<<<<<<<<<<<<
|
|---|
| 173 |
|
|---|
| 174 | split total into low bit (result) and high bit (new carry)
|
|---|
| 175 | [->+<]>
|
|---|
| 176 | [-<<[<]+>[->]>]
|
|---|
| 177 | <<<[->>+<<]
|
|---|
| 178 |
|
|---|
| 179 | shift in new result bit
|
|---|
| 180 | <<<<<<<<<<<<<<<<<[-]
|
|---|
| 181 | >>[-<<+>>]>>[-<<+>>]>>[-<<+>>]>>[-<<+>>]
|
|---|
| 182 | >>[-<<+>>]>>[-<<+>>]>>[-<<+>>]>>>>[-<<<<+>>>>]
|
|---|
| 183 |
|
|---|
| 184 | <<-]
|
|---|
| 185 |
|
|---|
| 186 | xor cipher byte with sector byte
|
|---|
| 187 | <[<[->-<]>[-<+>]]< <[<[->-<]>[-<+>]]<
|
|---|
| 188 | <[<[->-<]>[-<+>]]< <[<[->-<]>[-<+>]]<
|
|---|
| 189 | <[<[->-<]>[-<+>]]< <[<[->-<]>[-<+>]]<
|
|---|
| 190 | <[<[->-<]>[-<+>]]< <[<[->-<]>[-<+>]]
|
|---|
| 191 |
|
|---|
| 192 | combine bits into output byte
|
|---|
| 193 | > [-<<++>>] >>>> [-<<++>>] >>>> [-<<++>>] >>>> [-<<++>>]
|
|---|
| 194 | << [-<<<<++++>>>>] <<<<<<<< [-<<<<++++>>>>]
|
|---|
| 195 | >>>> [-<<<<<<<<++++++++++++++++>>>>>>>>]
|
|---|
| 196 |
|
|---|
| 197 | and write it out
|
|---|
| 198 | <<<<<<<<.[-]
|
|---|
| 199 |
|
|---|
| 200 | end of decryption loop
|
|---|
| 201 | <<]<]<]<] >>>>>
|
|---|
| 202 |
|
|---|
| 203 | end of decryption; if the encryption bit was clear:
|
|---|
| 204 | ]<[
|
|---|
| 205 |
|
|---|
| 206 | then just copy the rest of the sector (2027 bytes)
|
|---|
| 207 | >+++++[->+++++[->+++++++++[->+++++++++[->,.<]<]<]<],.,.>
|
|---|
| 208 |
|
|---|
| 209 | end of plaintext copy
|
|---|
| 210 | ]
|
|---|
| 211 |
|
|---|