mirror of
https://github.com/fluencelabs/crypto
synced 2025-04-24 22:32:17 +00:00
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
This commit is contained in:
parent
d938192ef6
commit
3e0d21d197
12
build.sbt
12
build.sbt
@ -14,7 +14,7 @@ val scalaV = scalaVersion := "2.12.5"
|
|||||||
|
|
||||||
val commons = Seq(
|
val commons = Seq(
|
||||||
scalaV,
|
scalaV,
|
||||||
version := "0.0.1",
|
version := "0.0.2",
|
||||||
fork in Test := true,
|
fork in Test := true,
|
||||||
parallelExecution in Test := false,
|
parallelExecution in Test := false,
|
||||||
organization := "one.fluence",
|
organization := "one.fluence",
|
||||||
@ -33,13 +33,13 @@ commons
|
|||||||
|
|
||||||
val CodecV = "0.0.3"
|
val CodecV = "0.0.3"
|
||||||
|
|
||||||
val CatsEffectV = "1.0.0-RC"
|
val CatsEffectV = "1.0.0-RC3"
|
||||||
|
|
||||||
val SloggingV = "0.6.1"
|
val SloggingV = "0.6.1"
|
||||||
|
|
||||||
val ScalatestV = "3.0.+"
|
val ScalatestV = "3.0.+"
|
||||||
|
|
||||||
val bouncyCastle = "org.bouncycastle" % "bcprov-jdk15on" % "1.59"
|
val bouncyCastle = "org.bouncycastle" % "bcprov-jdk15on" % "1.59"
|
||||||
|
|
||||||
enablePlugins(AutomateHeaderPlugin)
|
enablePlugins(AutomateHeaderPlugin)
|
||||||
|
|
||||||
@ -158,12 +158,12 @@ lazy val `crypto-jwt` = crossProject(JVMPlatform, JSPlatform)
|
|||||||
.settings(
|
.settings(
|
||||||
commons,
|
commons,
|
||||||
libraryDependencies ++= Seq(
|
libraryDependencies ++= Seq(
|
||||||
"one.fluence" %%% "codec-circe" % CodecV,
|
"one.fluence" %%% "codec-circe" % CodecV,
|
||||||
"org.scalatest" %%% "scalatest" % ScalatestV % Test
|
"org.scalatest" %%% "scalatest" % ScalatestV % Test
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
.jsSettings(
|
.jsSettings(
|
||||||
fork in Test := false,
|
fork in Test := false,
|
||||||
scalaJSModuleKind := ModuleKind.CommonJSModule
|
scalaJSModuleKind := ModuleKind.CommonJSModule
|
||||||
)
|
)
|
||||||
.enablePlugins(AutomateHeaderPlugin)
|
.enablePlugins(AutomateHeaderPlugin)
|
||||||
|
@ -23,6 +23,7 @@ import java.security.interfaces.ECPrivateKey
|
|||||||
|
|
||||||
import cats.Monad
|
import cats.Monad
|
||||||
import cats.data.EitherT
|
import cats.data.EitherT
|
||||||
|
import fluence.crypto.KeyPair.Secret
|
||||||
import fluence.crypto.{KeyPair, _}
|
import fluence.crypto.{KeyPair, _}
|
||||||
import fluence.crypto.hash.JdkCryptoHasher
|
import fluence.crypto.hash.JdkCryptoHasher
|
||||||
import fluence.crypto.signature.{SignAlgo, SignatureChecker, Signer}
|
import fluence.crypto.signature.{SignAlgo, SignatureChecker, Signer}
|
||||||
@ -72,6 +73,31 @@ class Ecdsa(curveType: String, scheme: String, hasher: Option[Crypto.Hasher[Arra
|
|||||||
} yield keyPair
|
} 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](
|
def sign[F[_]: Monad](
|
||||||
keyPair: KeyPair,
|
keyPair: KeyPair,
|
||||||
message: ByteVector
|
message: ByteVector
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
package fluence.crypto
|
package fluence.crypto
|
||||||
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
import java.math.BigInteger
|
||||||
|
|
||||||
import cats.data.EitherT
|
import cats.data.EitherT
|
||||||
import cats.instances.try_._
|
import cats.instances.try_._
|
||||||
@ -31,7 +32,7 @@ import scala.util.{Random, Try}
|
|||||||
|
|
||||||
class SignatureSpec extends WordSpec with Matchers {
|
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))
|
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
|
//try to store key into previously created file
|
||||||
storage.storeKeyPair(keys).attempt.unsafeRunSync().isLeft shouldBe true
|
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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user