BIP340

class BIP340(hostUrl: String = SODOT_RELAY_URL) : Scheme

BIP340 scheme implementation providing functionality for the FROST MPC protocol.

This class handles cryptographic operations using BIP340 keys, including:

  • Key generation via multi-party computation (MPC)

  • Distributed signing of messages

  • Secret share refreshing

  • Key resharing

  • Key import/export

  • Key derivation

  • Support for BIP-341 Taproot tweaking

Example Usage

/// Server side creates a room for 3 parties using API_KEY
/// Creating a room UUID should always happen on the server side
val numParties = 3
val threshold = 2
val apiKey = "MY_API_KEY"
val keygenRoomUuid = createRoom(numParties, apiKey)

/// All parties call initKeygen to get key generation IDs
val keygenInitResult = initKeygen()

/// All parties receive keygenIds from other parties
val keygenIds = listOf("keygenId1", "keygenId2")

/// All parties join the keygen room
val keygenResult = keygen(
keygenRoomUuid,
numParties,
threshold,
keygenInitResult.keygenSecret,
keygenIds
)

/// Pick the derivation path for the public key you want to sign for
val derivationPath = intArrayOf(44, 60, 0, 0, 0)

/// Option 1: Derive tweaked public key using the secret share from keygenResult
val pubkey = deriveTweakPubkey(keygenResult.secretShare, derivationPath, "")

/// Option 2: Derive tweaked public key using Xpub for more flexibility
val xpub = getXpub(keygenResult.secretShare)
val pubkeyFromXpub = deriveTweakPubkeyFromXpub(xpub, derivationPath, "")

/// To sign a message, create a signing room on the server side
val signingRoomUuid = createRoom(threshold, apiKey)
/// Your message in hex
val message = "deadbeef"

/// Threshold parties join the signing room
val signature = sign(signingRoomUuid, keygenResult.secretShare, message, derivationPath, "")
/// This signature can now be verified against pubkey

/// Refreshing the secret key material
val refreshRoomUuid = createRoom(numParties, apiKey)
/// All parties join the refresh room
val refreshResult = refresh(refreshRoomUuid, keygenResult.secretShare)
/// Note: refreshResult.pubkey == keygenResult.pubkey

/// Signing using the new secret key material
val signingRoomUuid2 = createRoom(threshold, apiKey)
val message2 = "deadbeefcafebabe"
val signature2 = sign(signingRoomUuid2, refreshResult.secretShare, message2, derivationPath, "")
/// This signature can now be verified against pubkey

Constructors

Link copied to clipboard
constructor(hostUrl: String = SODOT_RELAY_URL)

Functions

Link copied to clipboard
suspend fun createRoom(numParties: Int, apiKey: String): RoomUUID

Creates a room for multi-party computation.

Link copied to clipboard

Derives a private key from an extended private key (Xpriv).

Link copied to clipboard
fun deriveTweakPubkey(secretShare: BIP340SecretShare, derivationPath: IntArray, tweak: BIP340Tweak?): BIP340PublicKey

Derives a public key from an ECDSA secret share.

Link copied to clipboard

Derives a public key from an extended public key (Xpub).

Link copied to clipboard
suspend fun exportFullPrivateKey(roomUuid: RoomUUID, secretShare: BIP340SecretShare, toExportID: String): String?

Exports the full BIP340 private key.

Link copied to clipboard

Gets an export ID from an ECDSA secret share.

Link copied to clipboard
fun getXpub(secretShare: BIP340SecretShare): String

Gets an extended public key (Xpub) from an ECDSA secret share.

Link copied to clipboard
suspend fun importPrivateKeyImporter(roomUuid: RoomUUID, threshold: Int, privateKey: PrivateKey, keygenInitKeypair: KeygenPrivateKey, keygenIds: Array<KeygenID>, chaincode: ByteArray?): Pair<BIP340PublicKey, BIP340SecretShare>

Imports a BIP340 private key (importer).

Link copied to clipboard
suspend fun importPrivateKeyRecipient(roomUuid: RoomUUID, threshold: Int, keygenInitKeypair: KeygenPrivateKey, keygenIds: Array<KeygenID>): Pair<BIP340PublicKey, BIP340SecretShare>

Imports a BIP340 private key (recipient).

Link copied to clipboard

Initializes key generation for MPC protocols.

Link copied to clipboard
suspend fun keygen(roomUuid: String, numParties: Int, threshold: Int, keygenInitKeypair: KeygenPrivateKey, keygenIds: Array<KeygenID>): Pair<BIP340PublicKey, BIP340SecretShare>

Generates BIP340 keys using multi-party computation.

Link copied to clipboard

Exports a full BIP340 private key offline.

Link copied to clipboard

Refreshes the BIP340 secret share.

Link copied to clipboard
suspend fun reshareNewParty(roomUuid: RoomUUID, oldThreshold: Int, newThreshold: Int, keygenInitKeypair: KeygenPrivateKey, keygenIds: Array<KeygenID>): Pair<BIP340PublicKey, BIP340SecretShare>

Reshares a BIP340 key for a new party.

Link copied to clipboard
suspend fun reshareRemainingParty(roomUuid: RoomUUID, newThreshold: Int, secretShare: BIP340SecretShare, keygenIds: Array<KeygenID>): Pair<BIP340PublicKey, BIP340SecretShare>

Reshares a BIP340 key for a remaining party.

Link copied to clipboard
suspend fun sign(roomUuid: String, secretShare: BIP340SecretShare, msg: ByteArray, derivationPath: IntArray, tweak: BIP340Tweak?): BIP340Signature

Signs a message using BIP340 and multi-party computation.