2 Commits
0.0.1 ... 0.0.2

Author SHA1 Message Date
3e0d21d197 Ecdsa recreate pair from secret (#2)
* add possibility to re-create public key from private key for ECDSA alghorithm

* change version

* change version

* add comments, change version of cats-effect

* add comments, change method name

* change comment

* typo
2018-08-22 11:26:10 +03:00
d938192ef6 Initial Readme (#1)
* Badges

* Bintray resolver

* readme WIP

* More readme
2018-06-04 01:09:43 -07:00
5 changed files with 110 additions and 10 deletions

View File

@ -1,2 +1,63 @@
# crypto
[![Build Status](https://travis-ci.org/fluencelabs/crypto.svg?branch=master)](https://travis-ci.org/fluencelabs/crypto)
[![Gitter](https://badges.gitter.im/fluencelabs/crypto.svg)](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.

View File

@ -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)

View File

@ -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

View File

@ -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
}
}
}

View File

@ -1 +1 @@
sbt.version = 1.1.4
sbt.version = 1.2.1