summaryrefslogtreecommitdiff
path: root/src/utils
diff options
context:
space:
mode:
Diffstat (limited to 'src/utils')
-rw-r--r--src/utils/CryptoUtils.scala8
-rw-r--r--src/utils/FunctionUtils.scala2
-rw-r--r--src/utils/TupleUtils.scala10
-rw-r--r--src/utils/crypto/CBCCipher.scala21
4 files changed, 41 insertions, 0 deletions
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))
+}