Session creation
High level flow of TrioSession
- Configure/Implement transport layer NetworkClient
- Configure/Implement storage layer StorageClient
- Configure/Implement MessageSigner
- Create TrioSession
- Perform MPC actions
TrioSession is the main object which will be used to perform all of the MPC operations supported. To create TrioSession please follow the steps below.
Step 1 : Add library to your Project
-
Create new android studio project if you haven't.
-
Add SilentShard-Trio SDK using the instructions from the Installation Guide
Step 2 : Create new session
- We can Create TrioSession by calling SilentShard.ECDSA.trioInitiator() or SilentShard.EdDSA.trioInitiator() (whichever applies) by providing the following parameters
- Provide websocket client by using any of the below options :
- Providing WebsocketConfig object to let SDK use default WebsocketClient i.e. TrioNetworkClient.
- Providing custom NetworkClient overriding(extending) TrioNetworkClient 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 implement the StorageClient interface, which persists keyshares by an opaque
keyIdand declares itskeyTypeto match the session's algorithm. - Provide Message Signer (You need to implement the interface MessageSigner).
Example
- ECDSA
- EdDSA
MainActivity.kt
import com.silencelaboratories.silentshard.network.websocket.WebsocketConfig
import com.silencelaboratories.silentshard.storage.KeyType
import com.silencelaboratories.silentshard.storage.StorageClient
import com.silencelaboratories.silentshard.storage.StorageDao
import com.silencelaboratories.silentshard.storage.silentshard.ReconcileStoreDao
import com.silencelaboratories.silentshard.trio.SilentShard
import com.silencelaboratories.silentshard.trio.TrioSession
import com.silencelaboratories.silentshard.utils.MessageSigner
object Constants {
// Replace with your own
const val CLOUD_NODE_URI = "trio-server.demo.silencelaboratories.com"
// Replace with your own
const val PORT = 443
}
// Other party verifying-key/public-key. Replace with your own Verifying Key.
val cloudPublicKey = "9c4c79e942bbc3ff1d6ace7256404d701498056978cc4638c35832acdf821b1e"
// Create websocketConfig to let SilentShard use the default WebsocketClient.
val websocketConfig = WebsocketConfig(url = Constants.CLOUD_NODE_URI, port = Constants.PORT, isSecure = true)
// Create a storageClient to persist keyshares. The SDK owns keyshare storage and
// addresses every share by its keyId — your code never holds raw keyshare bytes.
val storageClient = object : StorageClient {
// The algorithm family this client stores keyshares for. Provide a separate
// client (with a matching keyType) per algorithm if you run more than one.
override val keyType = KeyType.ECDSA
/**
* An in-memory database. In the real world this should be a SQL-based DB,
* secure storage, or custom hardware — it is up to the implementing app.
*/
private val entries = mutableMapOf<String, ReconcileStoreDao>()
override suspend fun write(dao: StorageDao) {
require(dao is ReconcileStoreDao) { "Expected ReconcileStoreDao" }
// Persist the whole snapshot, including any null fields.
entries[dao.keyId] = dao
}
override suspend fun read(key: String): StorageDao? = entries[key]
}
// Create a messageSigner backed by your secure key storage (TEE / Keystore).
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 suspend fun sign(data: ByteArray): ByteArray {
TODO("Sign data using secure key (Secure Environment - TEE) and return the signature")
}
}
// For quick-start you can use the test message signer. Do not use it in production.
val testMessageSigner = SilentShard.ECDSA.TestMessageSigner
// Create a TrioSession for the ECDSA algorithm
val trioSession: TrioSession = SilentShard.ECDSA.trioInitiator(
// pass your messageSigner instance in production; do not use testMessageSigner
testMessageSigner, cloudPublicKey, websocketConfig, storageClient
)
// Or create a TrioSession with your own network client by extending TrioNetworkClient:
// val trioSession: TrioSession = SilentShard.ECDSA.trioInitiator(
// testMessageSigner, cloudPublicKey, CustomTrioNetworkClient(), storageClient
// )
MainActivity.kt
import com.silencelaboratories.silentshard.network.websocket.WebsocketConfig
import com.silencelaboratories.silentshard.storage.KeyType
import com.silencelaboratories.silentshard.storage.StorageClient
import com.silencelaboratories.silentshard.storage.StorageDao
import com.silencelaboratories.silentshard.storage.silentshard.ReconcileStoreDao
import com.silencelaboratories.silentshard.trio.SilentShard
import com.silencelaboratories.silentshard.trio.TrioSession
import com.silencelaboratories.silentshard.utils.MessageSigner
object Constants {
// Replace with your own
const val CLOUD_NODE_URI = "trio-server.demo.silencelaboratories.com"
// Replace with your own
const val PORT = 443
}
// Other party verifying-key/public-key. Replace with your own Verifying Key.
val cloudPublicKey = "9c4c79e942bbc3ff1d6ace7256404d701498056978cc4638c35832acdf821b1e"
// Create websocketConfig to let SilentShard use the default WebsocketClient.
val websocketConfig = WebsocketConfig(url = Constants.CLOUD_NODE_URI, port = Constants.PORT, isSecure = true)
// Create a storageClient to persist keyshares. The SDK owns keyshare storage and
// addresses every share by its keyId — your code never holds raw keyshare bytes.
val storageClient = object : StorageClient {
// The algorithm family this client stores keyshares for. Provide a separate
// client (with a matching keyType) per algorithm if you run more than one.
override val keyType = KeyType.EdDSA
/**
* An in-memory database. In the real world this should be a SQL-based DB,
* secure storage, or custom hardware — it is up to the implementing app.
*/
private val entries = mutableMapOf<String, ReconcileStoreDao>()
override suspend fun write(dao: StorageDao) {
require(dao is ReconcileStoreDao) { "Expected ReconcileStoreDao" }
// Persist the whole snapshot, including any null fields.
entries[dao.keyId] = dao
}
override suspend fun read(key: String): StorageDao? = entries[key]
}
// Create a messageSigner backed by your secure key storage (TEE / Keystore).
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 suspend fun sign(data: ByteArray): ByteArray {
TODO("Sign data using secure key (Secure Environment - TEE) and return the signature")
}
}
// For quick-start you can use the test message signer. Do not use it in production.
val testMessageSigner = SilentShard.EdDSA.TestMessageSigner
// Create a TrioSession for the EdDSA algorithm
val trioSession: TrioSession = SilentShard.EdDSA.trioInitiator(
// pass your messageSigner instance in production; do not use testMessageSigner
testMessageSigner, cloudPublicKey, websocketConfig, storageClient
)
// Or create a TrioSession with your own network client by extending TrioNetworkClient:
// val trioSession: TrioSession = SilentShard.EdDSA.trioInitiator(
// testMessageSigner, cloudPublicKey, CustomTrioNetworkClient(), 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 TrioSession (Three-Party) using ECDSA algorithm.
- ECDSA Provides factory methods for creating MPC session using ECDSA algorithm.
- TrioSession 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! 🎉