mirror of
https://github.com/fluencelabs/crypto
synced 2025-04-24 14:22:18 +00:00
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:
parent
3b7c2c3deb
commit
978634e450
@ -24,10 +24,10 @@ package fluence.crypto.cipher
|
||||
* @tparam P The type of plain text, input
|
||||
* @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]
|
||||
|
||||
}
|
||||
|
@ -17,7 +17,8 @@
|
||||
|
||||
package fluence.crypto.cipher
|
||||
|
||||
import scala.annotation.tailrec
|
||||
import cats.Monad
|
||||
import cats.syntax.functor._
|
||||
import scala.collection.Searching.{ Found, InsertionPoint, SearchResult }
|
||||
import scala.math.Ordering
|
||||
|
||||
@ -35,7 +36,7 @@ import scala.math.Ordering
|
||||
*/
|
||||
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.
|
||||
@ -49,28 +50,26 @@ object CryptoSearching {
|
||||
* sequence. A `InsertionPoint` value containing the index where the element would be inserted if
|
||||
* the search element is not found in the sequence.
|
||||
*/
|
||||
final def binarySearch[B](searchElem: B)(implicit ordering: Ordering[B], decrypt: A ⇒ B): SearchResult = {
|
||||
binarySearchRec(searchElem, 0, coll.length, ordering, decrypt)
|
||||
}
|
||||
|
||||
@tailrec
|
||||
private def binarySearchRec[B](elem: B, from: Int, to: Int, ordering: Ordering[B], decrypt: A ⇒ B): SearchResult = {
|
||||
|
||||
if (from == to) return InsertionPoint(from)
|
||||
|
||||
val idx = from + (to - from - 1) / 2
|
||||
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)
|
||||
final def binarySearch[B](searchElem: B)(implicit ordering: Ordering[B], decrypt: A ⇒ F[B]): F[SearchResult] = {
|
||||
F.tailRecM((0, coll.length)) {
|
||||
case (from, to) if from == to ⇒ F.pure(Right(InsertionPoint(from)))
|
||||
case (from, to) ⇒
|
||||
val idx = from + (to - from - 1) / 2
|
||||
decrypt(coll(idx)).map { d ⇒
|
||||
math.signum(ordering.compare(searchElem, d)) match {
|
||||
case -1 ⇒ Left((from, idx))
|
||||
case 1 ⇒ Left((idx + 1, to))
|
||||
case _ ⇒ Right(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)
|
||||
|
||||
implicit def search[A](array: Array[A]): CryptoSearchImpl[A] =
|
||||
implicit def search[F[_] : Monad, A](array: Array[A]): CryptoSearchImpl[F, A] =
|
||||
new CryptoSearchImpl(array)
|
||||
|
||||
}
|
||||
|
@ -19,29 +19,32 @@ package fluence.crypto.cipher
|
||||
|
||||
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.
|
||||
*/
|
||||
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 {
|
||||
|
||||
val forString: NoOpCrypt[String] = apply[String](
|
||||
serializer = _.getBytes,
|
||||
deserializer = bytes ⇒ new String(bytes))
|
||||
def forString[F[_] : Applicative]: NoOpCrypt[F, String] = apply[F, String](
|
||||
serializer = _.getBytes.pure[F],
|
||||
deserializer = bytes ⇒ new String(bytes).pure[F])
|
||||
|
||||
val forLong: NoOpCrypt[Long] = apply[Long](
|
||||
serializer = ByteBuffer.allocate(java.lang.Long.BYTES).putLong(_).array(),
|
||||
deserializer = bytes ⇒ ByteBuffer.wrap(bytes).getLong()
|
||||
def forLong[F[_] : Applicative]: NoOpCrypt[F, Long] = apply[F, Long](
|
||||
serializer = ByteBuffer.allocate(java.lang.Long.BYTES).putLong(_).array().pure[F],
|
||||
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)
|
||||
|
||||
}
|
||||
|
@ -1,30 +1,32 @@
|
||||
package fluence.crypto
|
||||
|
||||
import fluence.crypto.cipher.NoOpCrypt
|
||||
import cats.instances.try_._
|
||||
import org.scalatest.{ Matchers, WordSpec }
|
||||
|
||||
import scala.collection.Searching.{ Found, InsertionPoint }
|
||||
import scala.util.Try
|
||||
|
||||
class CryptoSearchingSpec extends WordSpec with Matchers {
|
||||
|
||||
"search" should {
|
||||
"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 encryptedElements = plainTextElements.map(crypt.encrypt)
|
||||
val encryptedElements = plainTextElements.map(t ⇒ crypt.encrypt(t).get)
|
||||
|
||||
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("D") shouldBe Found(3)
|
||||
encryptedElements.binarySearch("E") shouldBe Found(4)
|
||||
encryptedElements.binarySearch("B").get shouldBe Found(1)
|
||||
encryptedElements.binarySearch("D").get shouldBe Found(3)
|
||||
encryptedElements.binarySearch("E").get shouldBe Found(4)
|
||||
|
||||
encryptedElements.binarySearch("0") shouldBe InsertionPoint(0)
|
||||
encryptedElements.binarySearch("BB") shouldBe InsertionPoint(2)
|
||||
encryptedElements.binarySearch("ZZ") shouldBe InsertionPoint(5)
|
||||
encryptedElements.binarySearch("0").get shouldBe InsertionPoint(0)
|
||||
encryptedElements.binarySearch("BB").get shouldBe InsertionPoint(2)
|
||||
encryptedElements.binarySearch("ZZ").get shouldBe InsertionPoint(5)
|
||||
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user