Skip to content

Commit 72598aa

Browse files
ATL-6926: Clean up code and tests
1 parent ea11949 commit 72598aa

File tree

9 files changed

+127
-30
lines changed

9 files changed

+127
-30
lines changed

node/src/main/scala/io/iohk/atala/prism/node/crypto/CryptoUtils.scala

+7-9
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,15 @@ import org.bouncycastle.jce.spec.ECNamedCurveSpec
1111

1212
import java.math.BigInteger
1313
import java.security.spec.{ECParameterSpec, ECPoint, ECPrivateKeySpec, ECPublicKeySpec}
14+
import scala.util.Try
1415

1516
object CryptoUtils {
1617
def isSecp256k1(key: SecpPublicKey): Boolean = {
17-
val t = key
18-
t == t
18+
val params = ECNamedCurveTable.getParameterSpec("secp256k1")
19+
val curve = params.getCurve
20+
val x = new BigInteger(1, key.x)
21+
val y = new BigInteger(1, key.y)
22+
Try(curve.validatePoint(x, y)).isSuccess
1923
}
2024

2125
trait SecpPublicKey {
@@ -56,12 +60,6 @@ object CryptoUtils {
5660
}
5761
private[crypto] case class SecpPrivateKeyImpl(bytes: Array[Byte]) extends SecpPrivateKey {
5862
override def getEncoded: Array[Byte] = {
59-
// val PRIVATE_KEY_BYTE_SIZE = 32
60-
// val byteList = privateLey.asInstanceOf[ECPrivateKey].getD.toByteArray
61-
// val padding = Array.fill[Byte](PRIVATE_KEY_BYTE_SIZE - byteList.size) { 0 }
62-
// padding ++ byteList
63-
// The SDK was adding a padding that seems to later not be able to parse according to tests
64-
6563
privateLey
6664
.asInstanceOf[ECPrivateKey]
6765
.getD
@@ -149,7 +147,7 @@ object CryptoUtils {
149147

150148
def unsafetoPublicKeyFromUncompressed(bytes: Array[Byte]): SecpPublicKey = {
151149
val PRIVATE_KEY_BYTE_SIZE: Int = 32
152-
val pointSize = PRIVATE_KEY_BYTE_SIZE * 2 + 1
150+
val pointSize = PRIVATE_KEY_BYTE_SIZE * 2 + 1
153151
require(bytes.length == pointSize, s"Invalid public key bytes length, ${bytes.length}")
154152

155153
val uncompressedPrefix = bytes.head

node/src/test/scala/io/iohk/atala/prism/node/NodeExplorerServiceSpec.scala

+15-3
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,22 @@ import io.iohk.atala.prism.node.errors.NodeError
1818
import io.iohk.atala.prism.node.models.AtalaObjectStatus.{Pending, Scheduled}
1919
import io.iohk.atala.prism.node.models._
2020
import io.iohk.atala.prism.node.operations._
21-
import io.iohk.atala.prism.node.repositories.{AtalaOperationsRepository, MetricsCountersRepository, RequestNoncesRepository}
22-
import io.iohk.atala.prism.node.services.{BlockProcessingServiceSpec, NodeExplorerService, ObjectManagementService, StatisticsService}
21+
import io.iohk.atala.prism.node.repositories.{
22+
AtalaOperationsRepository,
23+
MetricsCountersRepository,
24+
RequestNoncesRepository
25+
}
26+
import io.iohk.atala.prism.node.services.{
27+
BlockProcessingServiceSpec,
28+
NodeExplorerService,
29+
ObjectManagementService,
30+
StatisticsService
31+
}
2332
import io.iohk.atala.prism.node.nonce.{ClientHelper, RequestAuthenticator}
24-
import io.iohk.atala.prism.protos.node_api.GetScheduledOperationsRequest.OperationType.{AnyOperationType, CreateDidOperationOperationType}
33+
import io.iohk.atala.prism.protos.node_api.GetScheduledOperationsRequest.OperationType.{
34+
AnyOperationType,
35+
CreateDidOperationOperationType
36+
}
2537
import io.iohk.atala.prism.protos.node_api.NodeExplorerServiceGrpc.NodeExplorerServiceBlockingClient
2638
import io.iohk.atala.prism.protos.node_api._
2739
import io.iohk.atala.prism.protos.node_models.SignedAtalaOperation

node/src/test/scala/io/iohk/atala/prism/node/crypto/CryptoTestUtils.scala

+1-3
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,8 @@ object CryptoTestUtils {
2525
)
2626
}
2727

28-
def generatePublicKey(): SecpPublicKey = generateKeyPair().publicKey
29-
3028
def generatePublicKeyData(): PublicKeyData = toPublicKeyData(
31-
generatePublicKey()
29+
generateKeyPair().publicKey
3230
)
3331

3432
def getUnderlyingKey(secpKey: SecpPublicKey): ECPublicKey = EC.INSTANCE.toPublicKeyFromCompressed(secpKey.compressed)

node/src/test/scala/io/iohk/atala/prism/node/crypto/CryptoTestsSpec.scala

+74-8
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,58 @@
11
package io.iohk.atala.prism.node.crypto
22

3-
import io.iohk.atala.prism.crypto.EC
3+
import io.iohk.atala.prism.crypto.signature.ECSignature
4+
import io.iohk.atala.prism.crypto.{EC, Sha256, Sha256Digest}
45
import io.iohk.atala.prism.node.crypto.CryptoUtils.{SecpECDSA, SecpPrivateKey, SecpPublicKey}
56
import org.scalatest.matchers.must.Matchers.convertToAnyMustWrapper
67
import org.scalatest.wordspec.AnyWordSpec
78

9+
import scala.util.Try
10+
11+
// The end goal of this test suit is to be deleted
12+
// Its purpose is to validate that the new implementation is
13+
// equivalent to the old SDK it is replacing, Once the SDK is
14+
// removed, then this tests should be deleted too
815
class CryptoTestsSpec extends AnyWordSpec {
916

10-
"crypto library" should {
17+
// public key encoding/decoding (compressed and uncompressed)
18+
// private key encoding/decoding
19+
// Signature validation
20+
21+
"cryptoUtils library" should {
22+
23+
// HASHING
24+
"Perform Sha256 hashing as the SDK" in {
25+
val msg = EC.INSTANCE.generateKeyPair().getPublicKey.getEncoded
26+
CryptoUtils.Sha256Hash.compute(msg).bytes mustBe Sha256.compute(msg).getValue.toVector
27+
}
28+
29+
"encode hashes as the SDK" in {
30+
val msg = EC.INSTANCE.generateKeyPair().getPublicKey.getEncoded
31+
CryptoUtils.Sha256Hash.compute(msg).hexEncoded mustBe Sha256.compute(msg).getHexValue
32+
}
33+
34+
"decode hex encoded hashes as the SDK" in {
35+
val hexEncoded = "c489e391b64dc18273047935edcb5e90d97da88b58ed9c2fa5e48dd3cf878f56"
36+
CryptoUtils.Sha256Hash.fromHex(hexEncoded).bytes mustBe Sha256Digest.fromHex(hexEncoded).getValue.toVector
37+
38+
val invalidHex = "W489e391b64dc18273047935edcb5e90d97da88b58ed9c2fa5e48dd3cf878f56"
39+
val failed1 = Try(CryptoUtils.Sha256Hash.fromHex(invalidHex))
40+
val failed2 = Try(Sha256Digest.fromHex(invalidHex))
41+
(failed1.isFailure && failed2.isFailure) mustBe true
42+
}
43+
44+
"decode hashes bytes as the SDK" in {
45+
val bytes = Array[Byte](-60, -119, -29, -111, -74, 77, -63, -126, 115, 4, 121, 53, -19, -53, 94, -112, -39, 125,
46+
-88, -117, 88, -19, -100, 47, -91, -28, -115, -45, -49, -121, -113, 86)
47+
CryptoUtils.Sha256Hash.fromBytes(bytes).bytes mustBe Sha256Digest.fromBytes(bytes).getValue.toVector
48+
49+
val invalidBytes = Array[Byte]()
50+
val failed1 = Try(CryptoUtils.Sha256Hash.fromBytes(invalidBytes))
51+
val failed2 = Try(Sha256Digest.fromBytes(invalidBytes))
52+
(failed1.isFailure && failed2.isFailure) mustBe true
53+
}
54+
55+
// SIGNING / VERIFICATION
1156
"can verify what SDK signs" in {
1257
val pair = EC.INSTANCE.generateKeyPair()
1358
val pub = pair.getPublicKey
@@ -20,7 +65,7 @@ class CryptoTestsSpec extends AnyWordSpec {
2065
SecpPublicKey.checkECDSASignature(msg, sig.getData, secp) mustBe true
2166
}
2267

23-
"can verify what it signs" in {
68+
"can verify what it signs" in {
2469
val pair = CryptoTestUtils.generateKeyPair()
2570
val pub = pair.publicKey
2671
val priv = pair.privateKey
@@ -31,8 +76,32 @@ class CryptoTestsSpec extends AnyWordSpec {
3176
SecpPublicKey.checkECDSASignature(msg, sig, pub) mustBe true
3277
}
3378

34-
"public key uncompressed encoding decoding" in {
35-
///
79+
"can produce valid signatures according to SDK" in {
80+
val pair = CryptoTestUtils.generateKeyPair()
81+
val pub = CryptoTestUtils.getUnderlyingKey(pair.publicKey)
82+
val priv = pair.privateKey
83+
84+
val msg = CryptoUtils.Sha256Hash.compute(pub.getEncodedCompressed).bytes.toArray
85+
val sig = new ECSignature(SecpECDSA.signBytes(msg, priv).bytes)
86+
87+
EC.INSTANCE.verifyBytes(msg, pub, sig) mustBe true
88+
}
89+
90+
// PUBLIC KEY ENCODING / DECODING
91+
"public key uncompressed encoding us compatible with SDK" in {
92+
val secpPublicKey = CryptoTestUtils.generateKeyPair().publicKey
93+
val sdkPubKey = EC.INSTANCE.generateKeyPair().getPublicKey
94+
95+
val uSecp = secpPublicKey.unCompressed
96+
val uSdk = sdkPubKey.getEncoded
97+
98+
// we parse the keys in the opposite library
99+
val parsedSDKKey = SecpPublicKey.unsafetoPublicKeyFromUncompressed(uSdk)
100+
val parsedSecpKey = EC.INSTANCE.toPublicKeyFromBytes(uSecp)
101+
102+
// we compare the encodings
103+
uSdk.toVector mustBe parsedSDKKey.unCompressed.toVector
104+
uSecp.toVector mustBe parsedSecpKey.getEncoded.toVector
36105
}
37106

38107
"private key encoding decoding" in {
@@ -41,9 +110,6 @@ class CryptoTestsSpec extends AnyWordSpec {
41110
val encodedPvKey = privK.getEncoded
42111
val secp = SecpPrivateKey.unsafefromBytesCompressed(encodedPvKey)
43112

44-
println(secp.bytes.toVector)
45-
println(secp.getEncoded.toVector)
46-
47113
encodedPvKey.toVector mustBe secp.getEncoded.toVector
48114
}
49115

node/src/test/scala/io/iohk/atala/prism/node/metrics/OperationsCounterSpec.scala

+6-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,12 @@ import io.iohk.atala.prism.node.services.BlockProcessingServiceSpec
66
import io.iohk.atala.prism.protos.node_models.{AtalaOperation, SignedAtalaOperation}
77
import org.scalatest.EitherValues._
88
import org.scalatest.matchers.must.Matchers
9-
import io.iohk.atala.prism.node.operations.{CreateDIDOperationSpec, DeactivateDIDOperationSpec, ProtocolVersionUpdateOperationSpec, UpdateDIDOperationSpec}
9+
import io.iohk.atala.prism.node.operations.{
10+
CreateDIDOperationSpec,
11+
DeactivateDIDOperationSpec,
12+
ProtocolVersionUpdateOperationSpec,
13+
UpdateDIDOperationSpec
14+
}
1015

1116
class OperationsCounterSpec extends AnyWordSpec with Matchers {
1217
"countReceivedAtalaOperations" should {

node/src/test/scala/io/iohk/atala/prism/node/operations/CreateDIDOperationSpec.scala

+1-2
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import org.scalatest.OptionValues._
2222

2323
object CreateDIDOperationSpec {
2424
def protoECKeyDataFromPublicKey(
25-
key: SecpPublicKey
25+
key: SecpPublicKey
2626
): node_models.ECKeyData =
2727
node_models.ECKeyData(
2828
curve = key.curveName,
@@ -43,7 +43,6 @@ object CreateDIDOperationSpec {
4343
protoECKeyDataFromPublicKey(keyPair.publicKey)
4444
}
4545

46-
4746
def randomCompressedECKeyData: CompressedECKeyData = {
4847
val keyPair = CryptoTestUtils.generateKeyPair()
4948
protoCompressedECKeyDataFromPublicKey(keyPair.publicKey)

node/src/test/scala/io/iohk/atala/prism/node/operations/UpdateDIDOperationSpec.scala

+6-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,12 @@ import io.iohk.atala.prism.node.crypto.CryptoTestUtils.SecpPair
1111
import io.iohk.atala.prism.node.crypto.CryptoUtils.Sha256Hash
1212
import io.iohk.atala.prism.node.grpc.ProtoCodecs
1313
import io.iohk.atala.prism.node.models.{DIDPublicKey, DIDService, KeyUsage, ProtocolConstants}
14-
import io.iohk.atala.prism.node.operations.CreateDIDOperationSpec.{issuingEcKeyData, masterEcKeyData, randomCompressedECKeyData, randomECKeyData}
14+
import io.iohk.atala.prism.node.operations.CreateDIDOperationSpec.{
15+
issuingEcKeyData,
16+
masterEcKeyData,
17+
randomCompressedECKeyData,
18+
randomECKeyData
19+
}
1520
import io.iohk.atala.prism.node.repositories.daos.{ContextDAO, PublicKeysDAO, ServicesDAO}
1621
import io.iohk.atala.prism.node.services.BlockProcessingServiceSpec
1722
import io.iohk.atala.prism.protos.node_models

node/src/test/scala/io/iohk/atala/prism/node/services/BlockProcessingServiceSpec.scala

+6-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,12 @@ import io.iohk.atala.prism.protos.models.TimestampInfo
99
import io.iohk.atala.prism.node.models.{AtalaOperationId, DidSuffix, Ledger, TransactionId}
1010
import io.iohk.atala.prism.node.{AtalaWithPostgresSpec, DataPreparation}
1111
import io.iohk.atala.prism.node.models.{AtalaOperationInfo, AtalaOperationStatus}
12-
import io.iohk.atala.prism.node.operations.{ApplyOperationConfig, CreateDIDOperation, CreateDIDOperationSpec, UpdateDIDOperationSpec}
12+
import io.iohk.atala.prism.node.operations.{
13+
ApplyOperationConfig,
14+
CreateDIDOperation,
15+
CreateDIDOperationSpec,
16+
UpdateDIDOperationSpec
17+
}
1318
import io.iohk.atala.prism.node.operations.UpdateDIDOperationSpec.{exampleAddKeyAction, exampleRemoveKeyAction}
1419
import io.iohk.atala.prism.node.repositories.daos.DIDDataDAO
1520
import io.iohk.atala.prism.protos.node_models.SignedAtalaOperation

node/src/test/scala/io/iohk/atala/prism/node/services/ObjectManagementServiceSpec.scala

+11-2
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,24 @@ import io.iohk.atala.prism.node.cardano.models.CardanoWalletError
1313
import io.iohk.atala.prism.node.crypto.CryptoTestUtils
1414
import io.iohk.atala.prism.node.crypto.CryptoTestUtils.SecpPair
1515
import io.iohk.atala.prism.node.crypto.CryptoUtils.Sha256Hash
16-
import io.iohk.atala.prism.node.errors.NodeError.{TooManyDidPublicKeysCreationAttempt, TooManyServiceCreationAttempt, UnsupportedProtocolVersion}
16+
import io.iohk.atala.prism.node.errors.NodeError.{
17+
TooManyDidPublicKeysCreationAttempt,
18+
TooManyServiceCreationAttempt,
19+
UnsupportedProtocolVersion
20+
}
1721
import io.iohk.atala.prism.node.grpc.ProtoCodecs
1822
import io.iohk.atala.prism.node.models.AtalaObjectTransactionSubmissionStatus.InLedger
1923
import io.iohk.atala.prism.node.models._
2024
import io.iohk.atala.prism.node.operations.{ApplyOperationConfig, CreateDIDOperationSpec}
2125
import io.iohk.atala.prism.node.operations.CreateDIDOperationSpec.{issuingEcKeyData, masterKeys}
2226
import io.iohk.atala.prism.node.operations.ProtocolVersionUpdateOperationSpec._
2327
import io.iohk.atala.prism.node.repositories.daos.{AtalaObjectTransactionSubmissionsDAO, AtalaObjectsDAO}
24-
import io.iohk.atala.prism.node.repositories.{AtalaObjectsTransactionsRepository, AtalaOperationsRepository, KeyValuesRepository, ProtocolVersionRepository}
28+
import io.iohk.atala.prism.node.repositories.{
29+
AtalaObjectsTransactionsRepository,
30+
AtalaOperationsRepository,
31+
KeyValuesRepository,
32+
ProtocolVersionRepository
33+
}
2534
import io.iohk.atala.prism.node.services.BlockProcessingServiceSpec.{createDidOperation, signOperation}
2635
import io.iohk.atala.prism.node.services.models.AtalaObjectNotification
2736
import io.iohk.atala.prism.node.{DataPreparation, PublicationInfo, UnderlyingLedger}

0 commit comments

Comments
 (0)