Skip to content

Commit

Permalink
Dev (#1)
Browse files Browse the repository at this point in the history
* feat(model): make data classes serializable

data classes are not serializable.  Serialization is needed to export Wallet to a json file

- Add Serializable annotation
- modify updateWallet to use upsert (update/insert)

* feat(dlt): add public and private key to DID

Public and private keys are not stored on the DID. Add required code to store them as hex strings
  • Loading branch information
Essbante authored Jan 4, 2022
1 parent 811d2ae commit 2ed36d3
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 34 deletions.
3 changes: 3 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
plugins {
kotlin("jvm") version "1.6.10"
kotlin("plugin.serialization") version "1.6.10"
id("maven-publish")
}

Expand All @@ -23,6 +24,8 @@ repositories {
dependencies {
implementation("org.jetbrains.kotlin:kotlin-stdlib:1.6.10")

implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.3.2")

implementation("org.litote.kmongo:kmongo:4.4.0")

// needed for cryptography primitives implementation
Expand Down
62 changes: 40 additions & 22 deletions src/main/kotlin/com/rootsid/wal/library/DLT.kt
Original file line number Diff line number Diff line change
Expand Up @@ -70,13 +70,13 @@ private fun waitUntilConfirmed(nodePublicApi: NodePublicApi, operationId: AtalaO
/**
* Derive key pair
*
* @param keyPaths
* @param keyPairs
* @param seed
* @param keyId
* @return
*/
private fun deriveKeyPair(keyPaths: MutableList<KeyPath>, seed: ByteArray, keyId: String): ECKeyPair {
val keyPathList = keyPaths.filter { it.keyId == keyId }
private fun deriveKeyPair(keyPairs: MutableList<KeyPair>, seed: ByteArray, keyId: String): ECKeyPair {
val keyPathList = keyPairs.filter { it.keyId == keyId }
if (keyPathList.isNotEmpty()) {
val keyPath = keyPathList[0]
return KeyGenerator.deriveKeyFromFullPath(seed, keyPath.didIdx, keyPath.keyType, keyPath.keyIdx)
Expand Down Expand Up @@ -119,36 +119,54 @@ fun newWallet(name: String, mnemonic: String, passphrase: String): Wallet {
fun newDid(wallet: Wallet, didAlias: String, issuer: Boolean): Wallet {
// To keep DID index sequential
val didIdx = wallet.dids.size
val keyPaths = mutableListOf<KeyPath>()
val masterKeyPathData = KeyPath(PrismDid.DEFAULT_MASTER_KEY_ID, didIdx, PrismKeyType.MASTER_KEY, 0)

val keyPairs = mutableListOf<KeyPair>()
val seed = KeyDerivation.binarySeed(MnemonicCode(wallet.mnemonic), wallet.passphrase)
val masterKeyPair = KeyGenerator.deriveKeyFromFullPath(
seed, masterKeyPathData.didIdx, masterKeyPathData.keyType, masterKeyPathData.keyIdx
seed, didIdx, PrismKeyType.MASTER_KEY, 0
)
val masterKeyPairData = KeyPair(
PrismDid.DEFAULT_MASTER_KEY_ID,
didIdx,
PrismKeyType.MASTER_KEY,
0,
masterKeyPair.privateKey.getHexEncoded(),
masterKeyPair.publicKey.getHexEncoded()
)
keyPaths.add(masterKeyPathData)
keyPairs.add(masterKeyPairData)

val unpublishedDid = if (issuer) {
val issuingKeyPathData = KeyPath(PrismDid.DEFAULT_ISSUING_KEY_ID, didIdx, PrismKeyType.ISSUING_KEY, 0)
val revocationKeyPathData = KeyPath(PrismDid.DEFAULT_REVOCATION_KEY_ID, didIdx, PrismKeyType.REVOCATION_KEY, 0)

keyPaths.add(issuingKeyPathData)
keyPaths.add(revocationKeyPathData)

val issuingKeyPair = KeyGenerator.deriveKeyFromFullPath(
seed, issuingKeyPathData.didIdx, issuingKeyPathData.keyType, issuingKeyPathData.keyIdx
seed, didIdx, PrismKeyType.ISSUING_KEY, 0
)
val revocationKeyPair = KeyGenerator.deriveKeyFromFullPath(
seed, revocationKeyPathData.didIdx, revocationKeyPathData.keyType, revocationKeyPathData.keyIdx
seed, didIdx, PrismKeyType.REVOCATION_KEY, 0
)
val issuingKeyPairData = KeyPair(
PrismDid.DEFAULT_ISSUING_KEY_ID,
didIdx,
PrismKeyType.ISSUING_KEY,
0,
issuingKeyPair.privateKey.getHexEncoded(),
issuingKeyPair.publicKey.getHexEncoded()
)
val revocationKeyPairData = KeyPair(
PrismDid.DEFAULT_REVOCATION_KEY_ID,
didIdx, PrismKeyType.REVOCATION_KEY,
0,
revocationKeyPair.privateKey.getHexEncoded(),
revocationKeyPair.publicKey.getHexEncoded()
)
keyPairs.add(issuingKeyPairData)
keyPairs.add(revocationKeyPairData)

PrismDid.buildExperimentalLongFormFromKeys(
masterKeyPair.publicKey, issuingKeyPair.publicKey, revocationKeyPair.publicKey
)
} else {
PrismDid.buildLongFormFromMasterPublicKey(masterKeyPair.publicKey)
}
wallet.dids.add(
DID(didAlias, didIdx, unpublishedDid.asCanonical().did.toString(), unpublishedDid.did.toString(), "", keyPaths)
DID(didAlias, didIdx, unpublishedDid.asCanonical().did.toString(), unpublishedDid.did.toString(), "", keyPairs)
)
return wallet
}
Expand Down Expand Up @@ -199,9 +217,9 @@ fun publishDid(wallet: Wallet, didAlias: String): Wallet {
val prismDid = PrismDid.fromString(did.uriLongForm)
// Key pairs to get private keys
val seed = KeyDerivation.binarySeed(MnemonicCode(wallet.mnemonic), wallet.passphrase)
val masterKeyPair = deriveKeyPair(did.keyPaths, seed, PrismDid.DEFAULT_MASTER_KEY_ID)
val issuingKeyPair = deriveKeyPair(did.keyPaths, seed, PrismDid.DEFAULT_ISSUING_KEY_ID)
val revocationKeyPair = deriveKeyPair(did.keyPaths, seed, PrismDid.DEFAULT_REVOCATION_KEY_ID)
val masterKeyPair = deriveKeyPair(did.keyPairs, seed, PrismDid.DEFAULT_MASTER_KEY_ID)
val issuingKeyPair = deriveKeyPair(did.keyPairs, seed, PrismDid.DEFAULT_ISSUING_KEY_ID)
val revocationKeyPair = deriveKeyPair(did.keyPairs, seed, PrismDid.DEFAULT_REVOCATION_KEY_ID)

val nodePayloadGenerator = NodePayloadGenerator(
prismDid as LongFormPrismDid,
Expand Down Expand Up @@ -250,7 +268,7 @@ fun issueCredential(wallet: Wallet, didAlias: String, credential: Credential): P
val claims = mutableListOf<CredentialClaim>()
// Key pairs to get private keys
val seed = KeyDerivation.binarySeed(MnemonicCode(wallet.mnemonic), wallet.passphrase)
val issuingKeyPair = deriveKeyPair(issuerDid.keyPaths, seed, PrismDid.DEFAULT_ISSUING_KEY_ID)
val issuingKeyPair = deriveKeyPair(issuerDid.keyPairs, seed, PrismDid.DEFAULT_ISSUING_KEY_ID)

claims.add(credential.claim.toCredentialClaim())

Expand Down Expand Up @@ -300,7 +318,7 @@ fun revokeCredential(wallet: Wallet, didAlias: String, credential: Credential) {
val nodeAuthApi = NodeAuthApiImpl(GrpcConfig.options)
// Key pairs to get private keys
val seed = KeyDerivation.binarySeed(MnemonicCode(wallet.mnemonic), wallet.passphrase)
val revocationKeyPair = deriveKeyPair(issuerDid.keyPaths, seed, PrismDid.DEFAULT_REVOCATION_KEY_ID)
val revocationKeyPair = deriveKeyPair(issuerDid.keyPairs, seed, PrismDid.DEFAULT_REVOCATION_KEY_ID)

val nodePayloadGenerator = NodePayloadGenerator(
PrismDid.fromString(issuerDid.uriLongForm) as LongFormPrismDid,
Expand Down
19 changes: 14 additions & 5 deletions src/main/kotlin/com/rootsid/wal/library/Model.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.rootsid.wal.library
import io.iohk.atala.prism.api.CredentialClaim
import io.iohk.atala.prism.identity.PrismDid
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.Serializable
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.json.Json

Expand All @@ -15,6 +16,7 @@ import kotlinx.serialization.json.Json
* @property dids
* @constructor Create empty Wallet
*/
@Serializable
data class Wallet(
val _id: String, // name
val mnemonic: List<String>,
Expand All @@ -30,16 +32,17 @@ data class Wallet(
* @property uriCanonical
* @property uriLongForm
* @property operationHash
* @property keyPaths
* @property keyPairs
* @constructor Create empty D i d
*/
@Serializable
data class DID(
val alias: String,
val didIdx: Int,
val uriCanonical: String,
val uriLongForm: String,
var operationHash: String = "",
var keyPaths: MutableList<KeyPath> = mutableListOf()
var keyPairs: MutableList<KeyPair> = mutableListOf()
)

/**
Expand All @@ -51,11 +54,14 @@ data class DID(
* @property keyIdx
* @constructor Create empty Key path
*/
data class KeyPath(
@Serializable
data class KeyPair(
val keyId: String,
val didIdx: Int,
val keyType: Int,
val keyIdx: Int
val keyIdx: Int,
val privateKey: String,
val publicKey: String
)

/**
Expand All @@ -65,6 +71,7 @@ data class KeyPath(
* @property proof
* @constructor Create empty Verified credential
*/
@Serializable
data class VerifiedCredential(
val encodedSignedCredential: String,
val proof: String
Expand All @@ -77,6 +84,7 @@ data class VerifiedCredential(
* @property content
* @constructor Create empty Claim
*/
@Serializable
data class Claim(
val subjectDid: String,
val content: String
Expand All @@ -101,11 +109,12 @@ fun Claim.toCredentialClaim() = CredentialClaim(
* @property verifiedCredential
* @constructor Create empty Credential
*/
@Serializable
data class Credential(
val _id: String,
// Plain json claim
val claim: Claim,
// Signed VC and proof
// Signed VC and proof (This is the real VC)
var verifiedCredential: VerifiedCredential,
// Required for revocation
var batchId: String,
Expand Down
9 changes: 2 additions & 7 deletions src/main/kotlin/com/rootsid/wal/library/Storage.kt
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
package com.rootsid.wal.library

import com.mongodb.client.MongoDatabase
import org.litote.kmongo.KMongo
import org.litote.kmongo.MongoOperator
import org.litote.kmongo.eq
import org.litote.kmongo.findOne
import org.litote.kmongo.getCollection
import org.litote.kmongo.updateOne
import org.litote.kmongo.*

/**
* Open db
Expand Down Expand Up @@ -104,6 +99,6 @@ fun didAliasExists(db: MongoDatabase, walletName: String, didAlias: String): Boo
*/
fun updateWallet(db: MongoDatabase, wallet: Wallet): Boolean {
val collection = db.getCollection<Wallet>("wallet")
val result = collection.updateOne(wallet)
val result = collection.updateOne(wallet, upsert())
return result.wasAcknowledged()
}

0 comments on commit 2ed36d3

Please sign in to comment.