From 9877ccf7fe7df38f8ecc65d01e9b46a98528502f Mon Sep 17 00:00:00 2001 From: iximeow Date: Wed, 26 Nov 2014 23:17:51 -0800 Subject: Add part of CBC mode --- src/utils/CryptoUtils.scala | 8 ++++++++ src/utils/FunctionUtils.scala | 2 ++ src/utils/TupleUtils.scala | 10 ++++++++++ src/utils/crypto/CBCCipher.scala | 21 +++++++++++++++++++++ test/Set1Spec.scala | 2 +- test/Set2Spec.scala | 5 +++++ 6 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 src/utils/TupleUtils.scala create mode 100644 src/utils/crypto/CBCCipher.scala diff --git a/src/utils/CryptoUtils.scala b/src/utils/CryptoUtils.scala index 5418895..2b4d38e 100644 --- a/src/utils/CryptoUtils.scala +++ b/src/utils/CryptoUtils.scala @@ -1,5 +1,9 @@ package ixee.cryptopals.utils +import ixee.cryptopals.utils.crypto.CBCCipher +import javax.crypto.Cipher +import javax.crypto.spec.SecretKeySpec + object CryptoUtils { def pkcs7pad(s: String, blockSize: Int) = { @@ -7,4 +11,8 @@ object CryptoUtils { s + s"${padLength.toChar}" * padLength } + def cbcDecryptInstance(ecbCipher: Cipher, key: SecretKeySpec): CBCCipher = { + ecbCipher.init(Cipher.DECRYPT_MODE, key) + new CBCCipher(ecbCipher) + } } diff --git a/src/utils/FunctionUtils.scala b/src/utils/FunctionUtils.scala index 84c141b..7456898 100644 --- a/src/utils/FunctionUtils.scala +++ b/src/utils/FunctionUtils.scala @@ -4,6 +4,8 @@ object FunctionUtils { // Because doing (_ f _).tupled confuses the inferencer... def tup[A, B, C](f: (A, B) => C): ((A, B)) => C = f.tupled + def iden[A](x: A) = x + implicit class Compositor[A, B](f: A => B) { def :|[C](g: B => C): A => C = f.andThen(g) } diff --git a/src/utils/TupleUtils.scala b/src/utils/TupleUtils.scala new file mode 100644 index 0000000..2a6dd6c --- /dev/null +++ b/src/utils/TupleUtils.scala @@ -0,0 +1,10 @@ +package ixee.cryptopals.utils + +object TupleUtils { + implicit class Tuple2[A, B](t: (A, B)) { + def mapAll[C, D](_1: A => C = ident, _2: B => D = ident): (C, D) = + (_1(t._1), _2(t._2)) + + def <-:(f: A => C + } +} diff --git a/src/utils/crypto/CBCCipher.scala b/src/utils/crypto/CBCCipher.scala new file mode 100644 index 0000000..e1ece8a --- /dev/null +++ b/src/utils/crypto/CBCCipher.scala @@ -0,0 +1,21 @@ +package ixee.cryptopals.utils.crypto + +import javax.crypto.Cipher + +class CBCCipher(cipher: Cipher, init: Seq[Byte]) { + var state: Seq[Byte] = init + var leftover: Seq[Byte] = Seq() + + def enc(data: Seq[Byte]): Seq[Byte] = { + (blocks, leftover) = blockized(leftover append data) + blocks.map(encBlock).reduce(_ append _) + } + + def encBlock(data: Seq[Byte]): Seq[Byte] = { + state = cipher.doFinal((data xor state).toArray) + state + } + + def blockized(data: Seq[Byte])(size: Int): (Seq[Seq[Byte]], Seq[Byte]) = + data.splitAt(data.length - (data.length % size)) +} diff --git a/test/Set1Spec.scala b/test/Set1Spec.scala index 67eadfc..7230d50 100644 --- a/test/Set1Spec.scala +++ b/test/Set1Spec.scala @@ -48,7 +48,7 @@ class Set1Spec extends IxeeSpec { } } - "Challenge 5: repeating-key xor" - { + "Challenge 5: repeating-key xor" in { val sourceText = """|Burning 'em, if you ain't quick and nimble |I go crazy when I hear a cymbal""".stripMargin diff --git a/test/Set2Spec.scala b/test/Set2Spec.scala index efcb5b0..df25f57 100644 --- a/test/Set2Spec.scala +++ b/test/Set2Spec.scala @@ -41,6 +41,11 @@ class Set2Spec extends IxeeSpec { } + "Challenge 10: Implement CBC mode" - { + + + + } } } -- cgit v1.1