Session creation
High level flow of DuoSession
- Configure/Implement transport layer NetworkClient
- Configure/Implement storage layer StorageClient
- Configure/Implement MessageSigner
- Create DuoSession
- Perform MPC actions
DuoSession is the main object which will be used to perform all of the MPC operations supported. To create DuoSession please follow the steps below.
Step 1 : Add library to your Project
-
Create new android studio project if you haven't.
-
Add SilentShard-Duo SDK using the instructions from the Installation Guide
Step 2 : Create new session
- We can Create DuoSession by calling SilentShard.ECDSA.createDuoSession() or SilentShard.EdDSA.createDuoSession() (whichever applies) by providing the following four parameters
- Provide websocket client by using any of the below options :
- Providing WebsocketConfig object to let SDK use default Network Client i.e. DuoNetworkClient.
- Providing custom NetworkClient overriding(extending) DuoNetworkClient to override existing connect, read or write, etc. methods to add your own logic/configuration or additional process.
- Provide cloud/server public key.
- Provide storage client. (You need to implement the interface StorageClient).
- Provide Message Signer (You need to implement the interface MessageSigner).
Example
- ECDSA
- EdDSA
MainActivity.kt
import com.silencelaboratories.silentshard.duo.initiator.DuoSession
import com.silencelaboratories.silentshard.duo.initiator.SilentShard
import com.silencelaboratories.silentshard.network.websocket.WebsocketConfig
import com.silencelaboratories.silentshard.storage.StorageClient
import com.silencelaboratories.silentshard.storage.StorageDao
import com.silencelaboratories.silentshard.storage.silentshard.ReconcileStoreDao
import com.silencelaboratories.silentshard.utils.MessageSigner
object Constants {
//Replace with your own
const val CLOUD_NODE_URI = "demo-server.silencelaboratories.com"
//Replace with your own
//const val PORT = "8080"
}
//Other party verifying-key/public-key. Replace with your own Verifying Key.
val cloudPublicKey = "01829099948d222f9731323900bc42bd3cc6f4e692f920705a9959b3e52378f188"
//Create websocketConfig to let SilentShard use default WebsocketClient.
//We can specify port or for Test Environment or Local Server you can configure like the following
//websocketConfig = WebsocketConfig(url = CLOUD_NODE_URI, port = PORT, isSecure = false)
val websocketConfig = WebsocketConfig(CLOUD_NODE_URI)
//Create storageClient instance to manage keyshare states
val storageClient = object : StorageClient {
/**
* Representing in-memory database. In real world it should be some SQL based DB or
* secure storage or custom hardware. It's up to the implementation app's use-case.
* */
private val keyshareDaoSet = mutableSetOf<ReconcileStoreDao>()
override suspend fun write(
dao: StorageDao,
) {
if (dao !is ReconcileStoreDao) {
throw IllegalArgumentException("Expected ReconcileStoreDao")
}
if (!keyshareDaoSet.add(dao)) {
keyshareDaoSet.remove(dao)
keyshareDaoSet.add(dao)
}
}
override suspend fun read(
key: String,
): ReconcileStoreDao? {
return keyshareDaoSet.find { it.keyId == key }
}
}
//Create messageSigner instance to sign message key
val messageSigner = object : MessageSigner {
override val verifyingKey: ByteArray
get() = TODO("Public key of secure key(Secure Environment - TEE)")
override val keyType: MessageSigner.KeyType
get() = TODO("Type of secure key(Secure Environment - TEE)")
override fun sign(data: ByteArray): ByteArray {
TODO("Sign data using secure key(Secure Environment - TEE) and return signature")
}
}
//For quick-start we can use test message signer. Do not use this in production
val testMessageSigner = SilentShard.ECDSA.TestMessageSigner
//Create duoSession for ECDSA algorithm
val duoSession: DuoSession = SilentShard.ECDSA.createDuoSession(
//pass your message signer instance i.e., messageSigner; do not use testMessageSigner in production
testMessageSigner, cloudPublicKey, websocketConfig, storageClient
)
//Create duoSession for ECDSA algorithm by providing your own network client
//by extending DuoNetworkClient
val duoSession: DuoSession = SilentShard.ECDSA.createDuoSession(
//pass your message signer instance i.e., messageSigner; do not use testMessageSigner in production
testMessageSigner, cloudPublicKey, CustomDuoNetworkClient(), storageClient
)
MainActivity.kt
import com.silencelaboratories.silentshard.duo.initiator.DuoSession
import com.silencelaboratories.silentshard.duo.initiator.SilentShard
import com.silencelaboratories.silentshard.network.websocket.WebsocketConfig
import com.silencelaboratories.silentshard.storage.StorageClient
import com.silencelaboratories.silentshard.storage.StorageDao
import com.silencelaboratories.silentshard.storage.silentshard.ReconcileStoreDao
import com.silencelaboratories.silentshard.utils.MessageSigner
object Constants {
//Replace with your own
const val CLOUD_NODE_URI = "demo-server.silencelaboratories.com"
//Replace with your own
//const val PORT = "8080"
}
//Other party verifying-key/public-key. Replace with your own Verifying Key.
val cloudPublicKey = "01829099948d222f9731323900bc42bd3cc6f4e692f920705a9959b3e52378f188"
//Create websocketConfig to let SilentShard use default WebsocketClient.
//We can specify port or for Test Environment or Local Server you can configure like the following
//websocketConfig = WebsocketConfig(url = CLOUD_NODE_URI, port = PORT, isSecure = false)
val websocketConfig = WebsocketConfig(CLOUD_NODE_URI)
//Create storageClient instance to manage keyshare states
val storageClient = object : StorageClient {
/**
* Representing in-memory database. In real world it should be some SQL based DB or
* secure storage or custom hardware. It's up to the implementation app's use-case.
* */
private val keyshareDaoSet = mutableSetOf<ReconcileStoreDao>()
override suspend fun write(
dao: StorageDao,
) {
if (dao !is ReconcileStoreDao) {
throw IllegalArgumentException("Expected ReconcileStoreDao")
}
if (!keyshareDaoSet.add(dao)) {
keyshareDaoSet.remove(dao)
keyshareDaoSet.add(dao)
}
}
override suspend fun read(
key: String,
): ReconcileStoreDao? {
return keyshareDaoSet.find { it.keyId == key }
}
}
//Create messageSigner instance to sign message key
val messageSigner = object : MessageSigner {
override val verifyingKey: ByteArray
get() = TODO("Public key of secure key(Secure Environment - TEE)")
override val keyType: MessageSigner.KeyType
get() = TODO("Type of secure key(Secure Environment - TEE)")
override fun sign(data: ByteArray): ByteArray {
TODO("Sign data using secure key(Secure Environment - TEE) and return signature")
}
}
//For quick-start we can use test message signer. Do not use this in production
val testMessageSigner = SilentShard.ECDSA.TestMessageSigner
//Create duoSession for EdDSA algorithm
val duoSession: DuoSession = SilentShard.EdDSA.createDuoSession(
//pass your message signer instance i.e., messageSigner; do not use testMessageSigner in production
testMessageSigner, cloudPublicKey, websocketConfig, storageClient
)
//Create duoSession for EdDSA algorithm by providing your own network client
//by extending DuoNetworkClient
val duoSession: DuoSession = SilentShard.EdDSA.createDuoSession(
//pass your message signer instance i.e., messageSigner; do not use testMessageSigner in production
testMessageSigner, cloudPublicKey, CustomDuoNetworkClient(), storageClient
)
CLOUD_NODE_URIis the URI of the cloud node.cloudPublicKeyis the cloud verifying key (Ed25519 public key).- This public key is used to verify the server's signature on each message
- See example here
- SilentShard Provides API for creating MPC DuoSession (Two-Party) using ECDSA algorithm.
- ECDSA Provides factory methods for creating MPC session using ECDSA algorithm.
- DuoSession Represents a two-party computation session that lets you perform MPC operations using SilentShard protocol.
You have now successfully set up the session and are ready to start performing MPC actions! 🎉