mirror of
https://github.com/fluencelabs/crypto
synced 2025-07-01 22:01:33 +00:00
Compare commits
2 Commits
Author | SHA1 | Date | |
---|---|---|---|
3e0d21d197 | |||
d938192ef6 |
63
README.md
63
README.md
@ -1,2 +1,63 @@
|
||||
# crypto
|
||||
[](https://travis-ci.org/fluencelabs/crypto)
|
||||
[](https://gitter.im/fluencelabs/crypto?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
|
||||
|
||||
# Сrypto
|
||||
|
||||
Cryptography for Scala and Scala.js, FP-flavoured.
|
||||
|
||||
APIs are mostly based on [codec](https://github.com/fluencelabs/codec) approach with partial bijections, using `CryptoError` case class for errors.
|
||||
|
||||
## Submodules
|
||||
|
||||
### crypto-core
|
||||
|
||||
Provides APIs and data types for various cryptographical operations, but without implementations.
|
||||
|
||||
This library should be added as dependency to both implementations of crypto algorithms and on the user side, if particular app doesn't require a particular algorithm.
|
||||
|
||||
### crypto-hashsign
|
||||
|
||||
Cross-platform hashing and signing algos.
|
||||
|
||||
Use a `fluence.crypto.hash.CryptoHashers` to access a hashing algorithm. Currently `Sha1` and `Sha256` are provided.
|
||||
|
||||
`fluence.crypto.ecdsa.Ecdsa.signAlgo` is an instance of `SignAlgo` with `ecdsa_secp256k1_sha256` under the hood.
|
||||
|
||||
### crypto-cipher
|
||||
|
||||
Encryption and decryption algorithms, coded as arrows and bijections. Currently contains `AES` ciphering.
|
||||
|
||||
### crypto-keystore
|
||||
|
||||
Provides a JSON format for serializing a keypair, using `codec-circe` for JSON processing.
|
||||
|
||||
For Scala on JVM, storing on the disc is implemented with use of `cats-effect`.
|
||||
|
||||
### crypto-jwt
|
||||
|
||||
Simplified JWT implementation, meaning a JSON-serialized header and claim with signature checking.
|
||||
|
||||
`codec-circe` is used for JSON encoding/decoding, and `codec-bits` for binary data manipulations.
|
||||
|
||||
## Installation
|
||||
|
||||
```scala
|
||||
// Bintray repo is used so far. Migration to Maven Central is planned
|
||||
resolvers += Resolver.bintrayRepo("fluencelabs", "releases")
|
||||
|
||||
val cryptoV = "0.0.1"
|
||||
|
||||
libraryDependencies ++= Seq(
|
||||
"one.fluence" %%% "crypto-core" % cryptoV, // basic types and APIs
|
||||
"one.fluence" %%% "crypto-hashsign" % cryptoV, // hashers and signatures
|
||||
"one.fluence" %%% "crypto-cipher" % cryptoV, // encoding and decoding
|
||||
"one.fluence" %%% "crypto-keystore" % cryptoV, // serialize and store a keypair
|
||||
"one.fluence" %%% "crypto-jwt" % cryptoV // simple JWT implementation
|
||||
)
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
Fluence is free software; you can redistribute it and/or modify it under the terms of the GNU Affero General Public License v3 (AGPLv3) as published by the Free Software Foundation.
|
||||
|
||||
Fluence includes some [external modules](https://github.com/fluencelabs/crypto/blob/master/build.sbt) that carry their own licensing.
|
15
build.sbt
15
build.sbt
@ -14,7 +14,7 @@ val scalaV = scalaVersion := "2.12.5"
|
||||
|
||||
val commons = Seq(
|
||||
scalaV,
|
||||
version := "0.0.1",
|
||||
version := "0.0.2",
|
||||
fork in Test := true,
|
||||
parallelExecution in Test := false,
|
||||
organization := "one.fluence",
|
||||
@ -25,20 +25,21 @@ val commons = Seq(
|
||||
headerLicense := Some(License.AGPLv3("2017", organizationName.value)),
|
||||
bintrayOrganization := Some("fluencelabs"),
|
||||
publishMavenStyle := true,
|
||||
bintrayRepository := "releases"
|
||||
bintrayRepository := "releases",
|
||||
resolvers += Resolver.bintrayRepo("fluencelabs", "releases")
|
||||
)
|
||||
|
||||
commons
|
||||
|
||||
val CodecV = "0.0.3"
|
||||
|
||||
val CatsEffectV = "1.0.0-RC"
|
||||
val CatsEffectV = "1.0.0-RC3"
|
||||
|
||||
val SloggingV = "0.6.1"
|
||||
|
||||
val ScalatestV = "3.0.+"
|
||||
|
||||
val bouncyCastle = "org.bouncycastle" % "bcprov-jdk15on" % "1.59"
|
||||
val bouncyCastle = "org.bouncycastle" % "bcprov-jdk15on" % "1.59"
|
||||
|
||||
enablePlugins(AutomateHeaderPlugin)
|
||||
|
||||
@ -157,12 +158,12 @@ lazy val `crypto-jwt` = crossProject(JVMPlatform, JSPlatform)
|
||||
.settings(
|
||||
commons,
|
||||
libraryDependencies ++= Seq(
|
||||
"one.fluence" %%% "codec-circe" % CodecV,
|
||||
"org.scalatest" %%% "scalatest" % ScalatestV % Test
|
||||
"one.fluence" %%% "codec-circe" % CodecV,
|
||||
"org.scalatest" %%% "scalatest" % ScalatestV % Test
|
||||
)
|
||||
)
|
||||
.jsSettings(
|
||||
fork in Test := false,
|
||||
fork in Test := false,
|
||||
scalaJSModuleKind := ModuleKind.CommonJSModule
|
||||
)
|
||||
.enablePlugins(AutomateHeaderPlugin)
|
||||
|
@ -23,6 +23,7 @@ import java.security.interfaces.ECPrivateKey
|
||||
|
||||
import cats.Monad
|
||||
import cats.data.EitherT
|
||||
import fluence.crypto.KeyPair.Secret
|
||||
import fluence.crypto.{KeyPair, _}
|
||||
import fluence.crypto.hash.JdkCryptoHasher
|
||||
import fluence.crypto.signature.{SignAlgo, SignatureChecker, Signer}
|
||||
@ -72,6 +73,31 @@ class Ecdsa(curveType: String, scheme: String, hasher: Option[Crypto.Hasher[Arra
|
||||
} yield keyPair
|
||||
}
|
||||
|
||||
/**
|
||||
* Restores pair of keys from the known secret key.
|
||||
* The public key will be the same each method call with the same secret key.
|
||||
* @param sk secret key
|
||||
* @return key pair
|
||||
*/
|
||||
def restorePairFromSecret[F[_]: Monad](sk: Secret): EitherT[F, CryptoError, KeyPair] =
|
||||
for {
|
||||
ecSpec ← EitherT.fromOption(
|
||||
Option(ECNamedCurveTable.getParameterSpec(curveType)),
|
||||
CryptoError("Parameter spec for the curve is not available.")
|
||||
)
|
||||
keyPair ← nonFatalHandling {
|
||||
val hex = sk.value.toHex
|
||||
val d = new BigInteger(hex, HEXradix)
|
||||
// to re-create public key from private we need to multiply known from curve point G with D (private key)
|
||||
// result will be point Q (public key)
|
||||
// https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm
|
||||
val g = ecSpec.getG
|
||||
val q = g.multiply(d)
|
||||
val pk = ByteVector(q.getEncoded(true))
|
||||
KeyPair.fromByteVectors(pk, sk.value)
|
||||
}("Could not generate KeyPair from private key. Unexpected.")
|
||||
} yield keyPair
|
||||
|
||||
def sign[F[_]: Monad](
|
||||
keyPair: KeyPair,
|
||||
message: ByteVector
|
||||
|
@ -18,6 +18,7 @@
|
||||
package fluence.crypto
|
||||
|
||||
import java.io.File
|
||||
import java.math.BigInteger
|
||||
|
||||
import cats.data.EitherT
|
||||
import cats.instances.try_._
|
||||
@ -31,7 +32,7 @@ import scala.util.{Random, Try}
|
||||
|
||||
class SignatureSpec extends WordSpec with Matchers {
|
||||
|
||||
def rndBytes(size: Int) = Random.nextString(10).getBytes
|
||||
def rndBytes(size: Int): Array[Byte] = Random.nextString(10).getBytes
|
||||
|
||||
def rndByteVector(size: Int) = ByteVector(rndBytes(size))
|
||||
|
||||
@ -125,5 +126,16 @@ class SignatureSpec extends WordSpec with Matchers {
|
||||
//try to store key into previously created file
|
||||
storage.storeKeyPair(keys).attempt.unsafeRunSync().isLeft shouldBe true
|
||||
}
|
||||
|
||||
"restore key pair from secret key" in {
|
||||
val algo = Ecdsa.signAlgo
|
||||
val testKeys = algo.generateKeyPair.unsafe(None)
|
||||
|
||||
val ecdsa = Ecdsa.ecdsa_secp256k1_sha256
|
||||
|
||||
val newKeys = ecdsa.restorePairFromSecret(testKeys.secretKey).extract
|
||||
|
||||
testKeys shouldBe newKeys
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1 +1 @@
|
||||
sbt.version = 1.1.4
|
||||
sbt.version = 1.2.1
|
||||
|
Reference in New Issue
Block a user