Kademlia grpc js (#99)

* update scalapb, copy grpc jvm files to js

* add npm dependencies

* generate js code with protoc, add it to js dependencies

* class facades

* add workbench, write facades, testing js

* fix js encryption and hashing

* tested facades for kademlia grpc service

* add js kademlia grpc service, refactoring

* example refactoring

* docs

* docs

* refactor versions

* refac, todo

* autogenerate

* generate protobuf for tests
This commit is contained in:
Dima 2018-03-28 10:19:30 +03:00 committed by GitHub
parent 6980f301d9
commit 672a40763a
6 changed files with 42 additions and 10 deletions

View File

@ -29,6 +29,7 @@ import scodec.bits.ByteVector
import scala.language.higherKinds import scala.language.higherKinds
import scala.scalajs.js import scala.scalajs.js
import scala.scalajs.js.JSConverters._ import scala.scalajs.js.JSConverters._
import scala.scalajs.js.typedarray.Uint8Array
/** /**
* Return in all js methods hex, because in the other case we will receive javascript objects * Return in all js methods hex, because in the other case we will receive javascript objects
@ -56,7 +57,7 @@ class Ecdsa(ec: EC, hasher: Option[CryptoHasher[Array[Byte], Array[Byte]]])
ec.keyFromPrivate(keyPair.secretKey.value.toHex, "hex") ec.keyFromPrivate(keyPair.secretKey.value.toHex, "hex")
}("Cannot get private key from key pair.") }("Cannot get private key from key pair.")
hash hash(message) hash hash(message)
signHex nonFatalHandling(secret.sign(hash).toDER("hex"))("Cannot sign message") signHex nonFatalHandling(secret.sign(new Uint8Array(hash)).toDER("hex"))("Cannot sign message")
} yield Signature(keyPair.publicKey, ByteVector.fromValidHex(signHex)) } yield Signature(keyPair.publicKey, ByteVector.fromValidHex(signHex))
} }
@ -78,7 +79,7 @@ class Ecdsa(ec: EC, hasher: Option[CryptoHasher[Array[Byte], Array[Byte]]])
ec.keyFromPublic(hex, "hex") ec.keyFromPublic(hex, "hex")
}("Incorrect public key format.") }("Incorrect public key format.")
hash hash(message) hash hash(message)
verify nonFatalHandling(public.verify(hash, signature.sign.toHex))("Cannot verify message.") verify nonFatalHandling(public.verify(new Uint8Array(hash), signature.sign.toHex))("Cannot verify message.")
_ EitherT.cond[F](verify, (), CryptoErr("Signature is not verified")) _ EitherT.cond[F](verify, (), CryptoErr("Signature is not verified"))
} yield () } yield ()
} }

View File

@ -19,6 +19,7 @@ package fluence.crypto.facade.ecdsa
import scala.scalajs.js import scala.scalajs.js
import scala.scalajs.js.annotation._ import scala.scalajs.js.annotation._
import scala.scalajs.js.typedarray.Uint8Array
//TODO hide enc argument in methods, make it `hex` by default //TODO hide enc argument in methods, make it `hex` by default
/** /**
@ -36,8 +37,8 @@ class EC(curve: String) extends js.Object {
@js.native @js.native
@JSImport("elliptic", "ec") @JSImport("elliptic", "ec")
class KeyPair(ec: EC, options: js.Dynamic) extends js.Object { class KeyPair(ec: EC, options: js.Dynamic) extends js.Object {
def verify(msg: js.Array[Byte], signature: String): Boolean = js.native def verify(msg: Uint8Array, signature: String): Boolean = js.native
def sign(msg: js.Array[Byte]): Signature = js.native def sign(msg: Uint8Array): Signature = js.native
def getPublic(compact: Boolean, enc: String): String = js.native def getPublic(compact: Boolean, enc: String): String = js.native
def getPrivate(enc: String): String = js.native def getPrivate(enc: String): String = js.native

View File

@ -19,6 +19,7 @@ package fluence.crypto.facade.ecdsa
import scala.scalajs.js import scala.scalajs.js
import scala.scalajs.js.annotation.JSImport import scala.scalajs.js.annotation.JSImport
import scala.scalajs.js.typedarray.Uint8Array
//TODO hide enc argument in methods, make it `hex` by default //TODO hide enc argument in methods, make it `hex` by default
/** /**
@ -27,13 +28,13 @@ import scala.scalajs.js.annotation.JSImport
@js.native @js.native
@JSImport("hash.js", "sha256") @JSImport("hash.js", "sha256")
class SHA256() extends js.Object { class SHA256() extends js.Object {
def update(msg: js.Array[Byte]): Unit = js.native def update(msg: Uint8Array): Unit = js.native
def digest(enc: String): String = js.native def digest(enc: String): String = js.native
} }
@js.native @js.native
@JSImport("hash.js", "sha1") @JSImport("hash.js", "sha1")
class SHA1() extends js.Object { class SHA1() extends js.Object {
def update(msg: js.Array[Byte]): Unit = js.native def update(msg: Uint8Array): Unit = js.native
def digest(enc: String): String = js.native def digest(enc: String): String = js.native
} }

View File

@ -21,20 +21,21 @@ import fluence.crypto.facade.ecdsa.{SHA1, SHA256}
import scodec.bits.ByteVector import scodec.bits.ByteVector
import scala.scalajs.js.JSConverters._ import scala.scalajs.js.JSConverters._
import scala.scalajs.js.typedarray.Uint8Array
object JsCryptoHasher { object JsCryptoHasher {
lazy val Sha256: CryptoHasher.Bytes = lazy val Sha256: CryptoHasher.Bytes =
CryptoHasher.buildM[Array[Byte], Array[Byte]] { msg CryptoHasher.buildM[Array[Byte], Array[Byte]] { msg
val sha256 = new SHA256() val sha256 = new SHA256()
sha256.update(msg.toJSArray) sha256.update(new Uint8Array(msg.toJSArray))
ByteVector.fromValidHex(sha256.digest("hex")).toArray ByteVector.fromValidHex(sha256.digest("hex")).toArray
}(_ ++ _) }(_ ++ _)
lazy val Sha1: CryptoHasher.Bytes = lazy val Sha1: CryptoHasher.Bytes =
CryptoHasher.buildM[Array[Byte], Array[Byte]] { msg CryptoHasher.buildM[Array[Byte], Array[Byte]] { msg
val sha1 = new SHA1() val sha1 = new SHA1()
sha1.update(msg.toJSArray) sha1.update(new Uint8Array(msg.toJSArray))
ByteVector.fromValidHex(sha1.digest("hex")).toArray ByteVector.fromValidHex(sha1.digest("hex")).toArray
}(_ ++ _) }(_ ++ _)
} }

View File

@ -19,8 +19,10 @@ package fluence.crypto
import fluence.crypto.facade.ecdsa.{SHA1, SHA256} import fluence.crypto.facade.ecdsa.{SHA1, SHA256}
import org.scalatest.{Matchers, WordSpec} import org.scalatest.{Matchers, WordSpec}
import scodec.bits.{Bases, ByteVector}
import scala.scalajs.js.JSConverters._ import scala.scalajs.js.JSConverters._
import scala.scalajs.js.typedarray.Uint8Array
class JSHashSpec extends WordSpec with Matchers { class JSHashSpec extends WordSpec with Matchers {
"js hasher" should { "js hasher" should {
@ -30,7 +32,7 @@ class JSHashSpec extends WordSpec with Matchers {
val sha256TesterHex = "513c17f8cf6ba96ce412cc2ae82f68821e9a2c6ae7a2fb1f5e46d08c387c8e65" val sha256TesterHex = "513c17f8cf6ba96ce412cc2ae82f68821e9a2c6ae7a2fb1f5e46d08c387c8e65"
val hasher = new SHA256() val hasher = new SHA256()
hasher.update(str.getBytes().toJSArray) hasher.update(new Uint8Array(str.getBytes().toJSArray))
val hex = hasher.digest("hex") val hex = hasher.digest("hex")
hex shouldBe sha256TesterHex hex shouldBe sha256TesterHex
} }
@ -40,9 +42,23 @@ class JSHashSpec extends WordSpec with Matchers {
val sha1TesterHex = "879db20eabcecea7d4736a8bae5bc64564b76b2f" val sha1TesterHex = "879db20eabcecea7d4736a8bae5bc64564b76b2f"
val hasher = new SHA1() val hasher = new SHA1()
hasher.update(str.getBytes().toJSArray) hasher.update(new Uint8Array(str.getBytes().toJSArray))
val hex = hasher.digest("hex") val hex = hasher.digest("hex")
hex shouldBe sha1TesterHex hex shouldBe sha1TesterHex
} }
"check unsigned array with sha1" in {
val arr = Array[Byte](3, -9, -31, 48, 10, 125, 51, -39, -20, -125, 123, 61, -36, 49, 76, 90, -16, 54, -61, 62, 50,
-116, -37, -88, -125, -32, -105, 120, 118, 13, -37, 33, -36)
val base64Check = "9keNwsj08vKTlwIpHAEYvsfpdP4="
val hasher = new SHA1()
hasher.update(new Uint8Array(arr.toJSArray))
val hex = hasher.digest("hex")
ByteVector.fromValidHex(hex, Bases.Alphabets.HexLowercase).toBase64 shouldBe base64Check
}
} }
} }

View File

@ -39,5 +39,17 @@ class JvmHashSpec extends WordSpec with Matchers {
val hasher = JdkCryptoHasher.Sha1 val hasher = JdkCryptoHasher.Sha1
ByteVector(hasher.hash(str.getBytes())).toHex shouldBe sha1TesterHex ByteVector(hasher.hash(str.getBytes())).toHex shouldBe sha1TesterHex
} }
"check unsigned array with sha1" in {
val arr = Array[Byte](3, -9, -31, 48, 10, 125, 51, -39, -20, -125, 123, 61, -36, 49, 76, 90, -16, 54, -61, 62, 50,
-116, -37, -88, -125, -32, -105, 120, 118, 13, -37, 33, -36)
val base64Check = "9keNwsj08vKTlwIpHAEYvsfpdP4="
val hasher = JdkCryptoHasher.Sha1
ByteVector(hasher.hash(arr)).toBase64 shouldBe base64Check
}
} }
} }