Crypto to f (#30)

* read and write ecdsa key into file

* file storage to F

* fix test

* add monad error

* header create

* store keys in json

* either -> try

* simplify config loading

* delete println

* add F to crypt

* comment fixes
This commit is contained in:
Dima 2018-02-06 13:52:13 +03:00 committed by GitHub
parent 3b7c2c3deb
commit 978634e450
4 changed files with 44 additions and 40 deletions

View File

@ -24,10 +24,10 @@ package fluence.crypto.cipher
* @tparam P The type of plain text, input * @tparam P The type of plain text, input
* @tparam C The type of cipher text, output * @tparam C The type of cipher text, output
*/ */
trait Crypt[P, C] { trait Crypt[F[_], P, C] {
def encrypt(plainText: P): C def encrypt(plainText: P): F[C]
def decrypt(cipherText: C): P def decrypt(cipherText: C): F[P]
} }

View File

@ -17,7 +17,8 @@
package fluence.crypto.cipher package fluence.crypto.cipher
import scala.annotation.tailrec import cats.Monad
import cats.syntax.functor._
import scala.collection.Searching.{ Found, InsertionPoint, SearchResult } import scala.collection.Searching.{ Found, InsertionPoint, SearchResult }
import scala.math.Ordering import scala.math.Ordering
@ -35,7 +36,7 @@ import scala.math.Ordering
*/ */
object CryptoSearching { object CryptoSearching {
class CryptoSearchImpl[A](coll: IndexedSeq[A]) { class CryptoSearchImpl[F[_], A](coll: IndexedSeq[A])(implicit F: Monad[F]) {
/** /**
* Searches the specified indexedSeq for the search element using the binary search algorithm. * Searches the specified indexedSeq for the search element using the binary search algorithm.
@ -49,28 +50,26 @@ object CryptoSearching {
* sequence. A `InsertionPoint` value containing the index where the element would be inserted if * sequence. A `InsertionPoint` value containing the index where the element would be inserted if
* the search element is not found in the sequence. * the search element is not found in the sequence.
*/ */
final def binarySearch[B](searchElem: B)(implicit ordering: Ordering[B], decrypt: A B): SearchResult = { final def binarySearch[B](searchElem: B)(implicit ordering: Ordering[B], decrypt: A F[B]): F[SearchResult] = {
binarySearchRec(searchElem, 0, coll.length, ordering, decrypt) F.tailRecM((0, coll.length)) {
} case (from, to) if from == to F.pure(Right(InsertionPoint(from)))
case (from, to)
@tailrec val idx = from + (to - from - 1) / 2
private def binarySearchRec[B](elem: B, from: Int, to: Int, ordering: Ordering[B], decrypt: A B): SearchResult = { decrypt(coll(idx)).map { d
math.signum(ordering.compare(searchElem, d)) match {
if (from == to) return InsertionPoint(from) case -1 Left((from, idx))
case 1 Left((idx + 1, to))
val idx = from + (to - from - 1) / 2 case _ Right(Found(idx))
math.signum(ordering.compare(elem, decrypt(coll(idx)))) match { }
case -1 binarySearchRec(elem, from, idx, ordering, decrypt) }
case 1 binarySearchRec(elem, idx + 1, to, ordering, decrypt)
case _ Found(idx)
} }
} }
} }
implicit def search[A](indexedSeq: IndexedSeq[A]): CryptoSearchImpl[A] = implicit def search[F[_] : Monad, A](indexedSeq: IndexedSeq[A]): CryptoSearchImpl[F, A] =
new CryptoSearchImpl(indexedSeq) new CryptoSearchImpl(indexedSeq)
implicit def search[A](array: Array[A]): CryptoSearchImpl[A] = implicit def search[F[_] : Monad, A](array: Array[A]): CryptoSearchImpl[F, A] =
new CryptoSearchImpl(array) new CryptoSearchImpl(array)
} }

View File

@ -19,29 +19,32 @@ package fluence.crypto.cipher
import java.nio.ByteBuffer import java.nio.ByteBuffer
import cats.Applicative
import cats.syntax.applicative._
/** /**
* No operation implementation. Just convert the element to bytes back and forth without any cryptography. * No operation implementation. Just convert the element to bytes back and forth without any cryptography.
*/ */
class NoOpCrypt[T](serializer: T Array[Byte], deserializer: Array[Byte] T) extends Crypt[T, Array[Byte]] { class NoOpCrypt[F[_], T](serializer: T F[Array[Byte]], deserializer: Array[Byte] F[T]) extends Crypt[F, T, Array[Byte]] {
def encrypt(plainText: T): Array[Byte] = serializer(plainText) def encrypt(plainText: T): F[Array[Byte]] = serializer(plainText)
def decrypt(cipherText: Array[Byte]): T = deserializer(cipherText) def decrypt(cipherText: Array[Byte]): F[T] = deserializer(cipherText)
} }
object NoOpCrypt { object NoOpCrypt {
val forString: NoOpCrypt[String] = apply[String]( def forString[F[_] : Applicative]: NoOpCrypt[F, String] = apply[F, String](
serializer = _.getBytes, serializer = _.getBytes.pure[F],
deserializer = bytes new String(bytes)) deserializer = bytes new String(bytes).pure[F])
val forLong: NoOpCrypt[Long] = apply[Long]( def forLong[F[_] : Applicative]: NoOpCrypt[F, Long] = apply[F, Long](
serializer = ByteBuffer.allocate(java.lang.Long.BYTES).putLong(_).array(), serializer = ByteBuffer.allocate(java.lang.Long.BYTES).putLong(_).array().pure[F],
deserializer = bytes ByteBuffer.wrap(bytes).getLong() deserializer = bytes ByteBuffer.wrap(bytes).getLong().pure[F]
) )
def apply[T](serializer: T Array[Byte], deserializer: Array[Byte] T): NoOpCrypt[T] = def apply[F[_], T](serializer: T F[Array[Byte]], deserializer: Array[Byte] F[T]): NoOpCrypt[F, T] =
new NoOpCrypt(serializer, deserializer) new NoOpCrypt(serializer, deserializer)
} }

View File

@ -1,30 +1,32 @@
package fluence.crypto package fluence.crypto
import fluence.crypto.cipher.NoOpCrypt import fluence.crypto.cipher.NoOpCrypt
import cats.instances.try_._
import org.scalatest.{ Matchers, WordSpec } import org.scalatest.{ Matchers, WordSpec }
import scala.collection.Searching.{ Found, InsertionPoint } import scala.collection.Searching.{ Found, InsertionPoint }
import scala.util.Try
class CryptoSearchingSpec extends WordSpec with Matchers { class CryptoSearchingSpec extends WordSpec with Matchers {
"search" should { "search" should {
"correct search plainText key in encrypted data" in { "correct search plainText key in encrypted data" in {
val crypt: NoOpCrypt[String] = NoOpCrypt.forString val crypt: NoOpCrypt[Try, String] = NoOpCrypt.forString
val plainTextElements = Array("A", "B", "C", "D", "E") val plainTextElements = Array("A", "B", "C", "D", "E")
val encryptedElements = plainTextElements.map(crypt.encrypt) val encryptedElements = plainTextElements.map(t crypt.encrypt(t).get)
import fluence.crypto.cipher.CryptoSearching._ import fluence.crypto.cipher.CryptoSearching._
implicit val decryptFn: (Array[Byte]) String = crypt.decrypt implicit val decryptFn: Array[Byte] Try[String] = crypt.decrypt
encryptedElements.binarySearch("B") shouldBe Found(1) encryptedElements.binarySearch("B").get shouldBe Found(1)
encryptedElements.binarySearch("D") shouldBe Found(3) encryptedElements.binarySearch("D").get shouldBe Found(3)
encryptedElements.binarySearch("E") shouldBe Found(4) encryptedElements.binarySearch("E").get shouldBe Found(4)
encryptedElements.binarySearch("0") shouldBe InsertionPoint(0) encryptedElements.binarySearch("0").get shouldBe InsertionPoint(0)
encryptedElements.binarySearch("BB") shouldBe InsertionPoint(2) encryptedElements.binarySearch("BB").get shouldBe InsertionPoint(2)
encryptedElements.binarySearch("ZZ") shouldBe InsertionPoint(5) encryptedElements.binarySearch("ZZ").get shouldBe InsertionPoint(5)
} }
} }