package ixee.cryptopals.test import com.ixee.IxeeSpec class Set2Spec extends IxeeSpec { import ixee.cryptopals.utils.ConversionUtils._ import ixee.cryptopals.utils.ByteUtils._ import ixee.cryptopals.utils.StreamUtils._ import ixee.cryptopals.utils.CryptoUtils._ import ixee.cryptopals.utils._ import ixee.cryptopals.utils.crypto.SchemeBuilder import ixee.cryptopals.solvers._ "Set2" - { "Challenge 9: Implement PKCS#7 padding" - { "when n bytes are missing" - { "fill with n bytes of value n" in { val text = "what a nice stri" * 16 * 2 def challenge9spec(expected: Byte) = { val truncated = text.dropRight(expected) val padString = pkcs7pad(truncated.asBytes, 256).takeRight(expected) val expectedPad = s"${expected.toChar}" * expected padString.asAscii mustBe expectedPad } for { x <- 1 to 255 } yield challenge9spec(x.toByte) } } } "Challenge 10: Implement CBC mode" - { "encryption then decryption produces the original data" in { val text = """|what a nice string the quick brown fox | and the lazy dog went for a jog in the park. |In touch with the ground |I'm on the hunt I'm after you |Smell like I sound, I'm lost in a crowd |And I'm hungry like the wolf |Straddle the line in discord and rhyme |I'm on the hunt I'm after you |Mouth is alive with juices like wine |And I'm hungry like the wolf | the wolf ate both of them.""".stripMargin val builder = SchemeBuilder("AES", "foobar, a nice s".asBytes) .cbc(Stream.from(10).take(16).map(_.toByte)) cbcDecrypt(builder)(cbcEncrypt(builder)(text.asBytes)) mustBe text.asBytes } "decrypts the example data" in { Challenge10.run mustBe Challenge6.expectation } } "Challenge 11: ECB/CBC detection" in { val input = "keke" * 32 val (mode, ciphertext) = Gloria.encryptify(input.asBytes) CryptoUtils.detectMode(ciphertext) mustBe mode // ...always. } "Challenge 12: ECB Decryption with user-specified prefix" - { "Extracts an unknown suffix from encrypted data" in { new String(Challenge12.run.toArray) mustBe Challenge12.expectation } } } }