• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

input-output-hk / atala-prism-building-blocks / 8539884318

03 Apr 2024 01:50PM UTC coverage: 31.674% (+0.2%) from 31.453%
8539884318

Pull #958

patlo-iog
chore: pr cleanup

Signed-off-by: Pat Losoponkul <pat.losoponkul@iohk.io>
Pull Request #958: fix: add shared-crypto module and apollo wrapper for other key types

74 of 161 new or added lines in 9 files covered. (45.96%)

433 existing lines in 86 files now uncovered.

4525 of 14286 relevant lines covered (31.67%)

0.32 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

84.75
/shared/crypto/src/main/scala/io/iohk/atala/shared/crypto/Prism14Apollo.scala
1
package io.iohk.atala.shared.crypto
2

3
import io.iohk.atala.prism.crypto.EC
4
import io.iohk.atala.prism.crypto.derivation.DerivationAxis
5
import io.iohk.atala.prism.crypto.derivation.KeyDerivation
6
import org.bouncycastle.jce.ECNamedCurveTable
7
import org.bouncycastle.jce.provider.BouncyCastleProvider
8
import org.bouncycastle.jce.spec.ECNamedCurveSpec
9
import zio.*
10

11
import java.security.KeyFactory
12
import java.security.interfaces.ECPrivateKey
13
import java.security.interfaces.ECPublicKey
14
import java.security.spec.{ECPrivateKeySpec, ECPublicKeySpec}
15
import scala.jdk.CollectionConverters.*
16
import scala.util.{Try, Success, Failure}
17

18
final case class Prism14Secp256k1PublicKey(publicKey: io.iohk.atala.prism.crypto.keys.ECPublicKey)
19
    extends Secp256k1PublicKey {
20

1✔
21
  override def getEncoded: Array[Byte] = getEncodedCompressed
NEW
22

×
23
  override def getEncodedUncompressed: Array[Byte] = publicKey.getEncoded()
24

1✔
25
  override def getEncodedCompressed: Array[Byte] = publicKey.getEncodedCompressed()
26

1✔
27
  override def toJavaPublicKey: ECPublicKey = {
28
    import KmpCompatUtil.*
1✔
29
    val x = publicKey.getCurvePoint.getX.getCoordinate.toScalaBigInt
1✔
30
    val y = publicKey.getCurvePoint.getY.getCoordinate.toScalaBigInt
1✔
31
    val keyFactory = KeyFactory.getInstance("EC", new BouncyCastleProvider())
1✔
32
    val ecParameterSpec = ECNamedCurveTable.getParameterSpec("secp256k1")
1✔
33
    val ecNamedCurveSpec = ECNamedCurveSpec(
1✔
34
      ecParameterSpec.getName(),
1✔
35
      ecParameterSpec.getCurve(),
1✔
36
      ecParameterSpec.getG(),
1✔
37
      ecParameterSpec.getN()
38
    )
1✔
NEW
39
    val ecPublicKeySpec = ECPublicKeySpec(java.security.spec.ECPoint(x.bigInteger, y.bigInteger), ecNamedCurveSpec)
×
40
    keyFactory.generatePublic(ecPublicKeySpec).asInstanceOf[java.security.interfaces.ECPublicKey]
41
  }
42

1✔
NEW
43
  override def verify(data: Array[Byte], signature: Array[Byte]): Try[Unit] = Try {
×
NEW
44
    val sig = EC.INSTANCE.toSignatureFromBytes(signature)
×
45
    EC.INSTANCE.verifyBytes(data, publicKey, sig)
1✔
46
  }.flatMap(isValid => if (isValid) Success(()) else Failure(Exception("The signature verification does not match")))
47

48
}
49

50
final case class Prism14Secp256k1PrivateKey(privateKey: io.iohk.atala.prism.crypto.keys.ECPrivateKey)
51
    extends Secp256k1PrivateKey {
52

1✔
53
  override def toPublicKey: Secp256k1PublicKey = Prism14Secp256k1PublicKey(
1✔
54
    EC.INSTANCE.toPublicKeyFromPrivateKey(privateKey)
55
  )
56

1✔
57
  override def toJavaPrivateKey: ECPrivateKey = {
1✔
58
    val bytes = privateKey.getEncoded()
1✔
59
    val keyFactory = KeyFactory.getInstance("EC", new BouncyCastleProvider())
1✔
60
    val ecParameterSpec = ECNamedCurveTable.getParameterSpec("secp256k1")
1✔
61
    val ecNamedCurveSpec = ECNamedCurveSpec(
1✔
62
      ecParameterSpec.getName(),
1✔
63
      ecParameterSpec.getCurve(),
1✔
64
      ecParameterSpec.getG(),
1✔
65
      ecParameterSpec.getN()
66
    )
1✔
NEW
67
    val ecPrivateKeySpec = ECPrivateKeySpec(java.math.BigInteger(1, bytes), ecNamedCurveSpec)
×
68
    keyFactory.generatePrivate(ecPrivateKeySpec).asInstanceOf[java.security.interfaces.ECPrivateKey]
69
  }
70

1✔
71
  override def getEncoded: Array[Byte] = privateKey.getEncoded()
72

1✔
73
  override def sign(data: Array[Byte]): Array[Byte] = EC.INSTANCE.signBytes(data, privateKey).getEncoded
74

75
}
76

77
object Prism14Secp256k1Ops extends Secp256k1KeyOps {
78

1✔
79
  override def generateKeyPair: UIO[Secp256k1KeyPair] =
1✔
80
    ZIO.attemptBlocking {
1✔
81
      val keyPair = EC.INSTANCE.generateKeyPair()
82
      Secp256k1KeyPair(
1✔
83
        Prism14Secp256k1PublicKey(keyPair.getPublicKey()),
1✔
84
        Prism14Secp256k1PrivateKey(keyPair.getPrivateKey()),
85
      )
86
    }.orDie
87

1✔
88
  override def privateKeyFromEncoded(bytes: Array[Byte]): Try[Secp256k1PrivateKey] =
1✔
89
    Try(Prism14Secp256k1PrivateKey(EC.INSTANCE.toPrivateKeyFromBytes(bytes)))
90

1✔
NEW
91
  override def publicKeyFromEncoded(bytes: Array[Byte]): Try[Secp256k1PublicKey] =
×
NEW
92
    Try(EC.INSTANCE.toPublicKeyFromBytes(bytes))
×
93
      .orElse(Try(EC.INSTANCE.toPublicKeyFromCompressed(bytes)))
1✔
94
      .map(Prism14Secp256k1PublicKey.apply)
95

1✔
96
  override def deriveKeyPair(seed: Array[Byte])(path: DerivationPath*): UIO[Secp256k1KeyPair] =
1✔
97
    ZIO.attempt {
98
      val extendedKey = path
1✔
99
        .foldLeft(KeyDerivation.INSTANCE.derivationRoot(seed)) { case (extendedKey, p) =>
100
          val axis = p match {
1✔
NEW
101
            case DerivationPath.Hardened(i) => DerivationAxis.hardened(i)
×
102
            case DerivationPath.Normal(i)   => DerivationAxis.normal(i)
103
          }
1✔
104
          extendedKey.derive(axis)
105
        }
1✔
106
      val prism14KeyPair = extendedKey.keyPair()
107
      Secp256k1KeyPair(
1✔
108
        Prism14Secp256k1PublicKey(prism14KeyPair.getPublicKey()),
1✔
109
        Prism14Secp256k1PrivateKey(prism14KeyPair.getPrivateKey())
110
      )
111
    }.orDie
112

1✔
113
  override def randomBip32Seed: UIO[(Array[Byte], Seq[String])] =
1✔
114
    ZIO.attemptBlocking {
1✔
115
      val mnemonic = KeyDerivation.INSTANCE.randomMnemonicCode()
1✔
NEW
116
      val words = mnemonic.getWords().asScala.toList
×
117
      KeyDerivation.INSTANCE.binarySeed(mnemonic, "") -> words
118
    }.orDie
119

120
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc