# sodot

```
import "github.com/sodot-rs/sodot-go-sdk"
```

Sodot Go module provides the ability to run TSS protocols for both ECDSA and Ed25519.

## Index

* [Constants](#constants)
* [type BIP340](#type-bip340)
  * [func NewBIP340(hostUrl string) BIP340](#func-newbip340)
  * [func (bip340 BIP340) CreateRoom(numParties uint16, apiKey string) (RoomUUID, error)](#func-bip340-createroom)
  * [func (bip340 BIP340) DerivePrivateKeyFromXpriv(xpriv string, derivationPath \[\]uint32) (PrivateKey, error)](#func-bip340-deriveprivatekeyfromxpriv)
  * [func (bip340 BIP340) DeriveTweakPubkey(share BIP340SecretShare, derivationPath \[\]uint32, tweak \*\[32\]byte) (BIP340PublicKey, error)](#func-bip340-derivetweakpubkey)
  * [func (bip340 BIP340) DeriveTweakPubkeyFromXpub(xpub string, derivationPath \[\]uint32, tweak \*\[32\]byte) (BIP340PublicKey, error)](#func-bip340-derivetweakpubkeyfromxpub)
  * [func (bip340 BIP340) ExportFullPrivateKey(roomUuid RoomUUID, share BIP340SecretShare, toExportID KeygenID) (string, error)](#func-bip340-exportfullprivatekey)
  * [func (bip340 BIP340) ExportID(share BIP340SecretShare) (KeygenID, error)](#func-bip340-exportid)
  * [func (bip340 BIP340) GetXpub(share BIP340SecretShare) (string, error)](#func-bip340-getxpub)
  * [func (bip340 BIP340) ImportPrivateKeyImporter(roomUuid RoomUUID, threshold uint16, privateKey PrivateKey, keygenPrivateKey KeygenPrivateKey, keygenIDs \[\]KeygenID) (BIP340SecretShare, BIP340PublicKey, error)](#func-bip340-importprivatekeyimporter)
  * [func (bip340 BIP340) ImportPrivateKeyRecipient(roomUuid RoomUUID, threshold uint16, keygenPrivateKey KeygenPrivateKey, keygenIDs \[\]KeygenID) (BIP340SecretShare, BIP340PublicKey, error)](#func-bip340-importprivatekeyrecipient)
  * [func (bip340 BIP340) InitKeygen() (KeygenID, KeygenPrivateKey, error)](#func-bip340-initkeygen)
  * [func (bip340 BIP340) Keygen(roomUuid RoomUUID, numParties uint16, threshold uint16, keygenPrivateKey KeygenPrivateKey, keygenIDs \[\]KeygenID) (BIP340SecretShare, BIP340PublicKey, error)](#func-bip340-keygen)
  * [func (bip340 BIP340) OfflineExportFullPrivateKey(shares \[\]BIP340SecretShare) (string, error)](#func-bip340-offlineexportfullprivatekey)
  * [func (bip340 BIP340) Refresh(roomUuid RoomUUID, share BIP340SecretShare) (BIP340SecretShare, BIP340PublicKey, error)](#func-bip340-refresh)
  * [func (bip340 BIP340) ReshareNewParty(roomUuid RoomUUID, newThreshold uint16, keygenPrivateKey KeygenPrivateKey, keygenIDs \[\]KeygenID) (BIP340SecretShare, BIP340PublicKey, error)](#func-bip340-resharenewparty)
  * [func (bip340 BIP340) ReshareRemainingParty(roomUuid RoomUUID, newThreshold uint16, share BIP340SecretShare, keygenIDs \[\]KeygenID) (BIP340SecretShare, BIP340PublicKey, error)](#func-bip340-reshareremainingparty)
  * [func (bip340 BIP340) Sign(roomUuid RoomUUID, share BIP340SecretShare, msg \[\]byte, derivationPath \[\]uint32, tweak \*\[32\]byte) (BIP340Signature, error)](#func-bip340-sign)
* [type BIP340PublicKey](#type-bip340publickey)
  * [func BIP340PublicKeyFromString(s string) (BIP340PublicKey, error)](#func-bip340publickeyfromstring)
  * [func (pubkey \*BIP340PublicKey) String() string](#func-bip340publickey-string)
* [type BIP340SecretShare](#type-bip340secretshare)
  * [func (share BIP340SecretShare) Bytes() \[\]byte](#func-bip340secretshare-bytes)
* [type BIP340Signature](#type-bip340signature)
  * [func (sig \*BIP340Signature) String() string](#func-bip340signature-string)
* [type Ecdsa](#type-ecdsa)
  * [func NewEcdsa(hostUrl string) Ecdsa](#func-newecdsa)
  * [func (ecdsa Ecdsa) CreateRoom(numParties uint16, apiKey string) (RoomUUID, error)](#func-ecdsa-createroom)
  * [func (ecdsa Ecdsa) DerivePrivateKeyFromXpriv(xpriv string, derivationPath \[\]uint32) (PrivateKey, error)](#func-ecdsa-deriveprivatekeyfromxpriv)
  * [func (ecdsa Ecdsa) DerivePubkey(share EcdsaSecretShare, derivationPath \[\]uint32) (EcdsaPublicKey, error)](#func-ecdsa-derivepubkey)
  * [func (ecdsa Ecdsa) DerivePubkeyFromXpub(xpub string, derivationPath \[\]uint32) (EcdsaPublicKey, error)](#func-ecdsa-derivepubkeyfromxpub)
  * [func (ecdsa Ecdsa) ExportFullPrivateKey(roomUuid RoomUUID, share EcdsaSecretShare, toExportID KeygenID) (string, error)](#func-ecdsa-exportfullprivatekey)
  * [func (ecdsa Ecdsa) ExportID(share EcdsaSecretShare) (KeygenID, error)](#func-ecdsa-exportid)
  * [func (ecda Ecdsa) GetXpub(share EcdsaSecretShare) (string, error)](#func-ecdsa-getxpub)
  * [func (ecdsa Ecdsa) ImportPrivateKeyImporter(roomUuid RoomUUID, threshold uint16, privateKey PrivateKey, keygenPrivateKey KeygenPrivateKey, keygenIDs \[\]KeygenID) (EcdsaSecretShare, EcdsaPublicKey, error)](#func-ecdsa-importprivatekeyimporter)
  * [func (ecdsa Ecdsa) ImportPrivateKeyRecipient(roomUuid RoomUUID, threshold uint16, keygenPrivateKey KeygenPrivateKey, keygenIDs \[\]KeygenID) (EcdsaSecretShare, EcdsaPublicKey, error)](#func-ecdsa-importprivatekeyrecipient)
  * [func (ecdsa Ecdsa) InitKeygen() (KeygenID, KeygenPrivateKey, error)](#func-ecdsa-initkeygen)
  * [func (ecdsa Ecdsa) Keygen(roomUuid RoomUUID, numParties uint16, threshold uint16, keygenPrivateKey KeygenPrivateKey, keygenIDs \[\]KeygenID) (EcdsaSecretShare, EcdsaPublicKey, error)](#func-ecdsa-keygen)
  * [func (ecdsa Ecdsa) OfflineExportFullPrivateKey(shares \[\]EcdsaSecretShare) (string, error)](#func-ecdsa-offlineexportfullprivatekey)
  * [func (ecdsa Ecdsa) Refresh(roomUuid RoomUUID, share EcdsaSecretShare) (EcdsaSecretShare, EcdsaPublicKey, error)](#func-ecdsa-refresh)
  * [func (ecdsa Ecdsa) ReshareNewParty(roomUuid RoomUUID, newThreshold uint16, keygenPrivateKey KeygenPrivateKey, keygenIDs \[\]KeygenID) (EcdsaSecretShare, EcdsaPublicKey, error)](#func-ecdsa-resharenewparty)
  * [func (ecdsa Ecdsa) ReshareRemainingParty(roomUuid RoomUUID, newThreshold uint16, share EcdsaSecretShare, keygenIDs \[\]KeygenID) (EcdsaSecretShare, EcdsaPublicKey, error)](#func-ecdsa-reshareremainingparty)
  * [func (ecdsa Ecdsa) Sign(roomUuid RoomUUID, share EcdsaSecretShare, msgHash MessageHash, derivationPath \[\]uint32) (EcdsaSignature, error)](#func-ecdsa-sign)
* [type EcdsaPublicKey](#type-ecdsapublickey)
  * [func EcdsaPublicKeyFromString(s string) (EcdsaPublicKey, error)](#func-ecdsapublickeyfromstring)
  * [func (pubkey \*EcdsaPublicKey) Equal(other EcdsaPublicKey) bool](#func-ecdsapublickey-equal)
  * [func (pubkey \*EcdsaPublicKey) SerializeCompressed() (ret \[33\]byte)](#func-ecdsapublickey-serializecompressed)
  * [func (pubkey \*EcdsaPublicKey) SerializeUncompressed() \[65\]byte](#func-ecdsapublickey-serializeuncompressed)
  * [func (pubkey \*EcdsaPublicKey) String() string](#func-ecdsapublickey-string)
* [type EcdsaSecretShare](#type-ecdsasecretshare)
  * [func (share EcdsaSecretShare) Bytes() \[\]byte](#func-ecdsasecretshare-bytes)
* [type EcdsaSignature](#type-ecdsasignature)
  * [func (sig EcdsaSignature) DER() \[\]byte](#func-ecdsasignature-der)
  * [func (sig EcdsaSignature) Equal(other EcdsaSignature) bool](#func-ecdsasignature-equal)
  * [func (sig EcdsaSignature) R() \[\]byte](#func-ecdsasignature-r)
  * [func (sig EcdsaSignature) S() \[\]byte](#func-ecdsasignature-s)
  * [func (sig EcdsaSignature) String() string](#func-ecdsasignature-string)
  * [func (sig EcdsaSignature) V() byte](#func-ecdsasignature-v)
* [type Ed25519](#type-ed25519)
  * [func NewEd25519(hostUrl string) Ed25519](#func-newed25519)
  * [func (ed25519 Ed25519) CreateRoom(numParties uint16, apiKey string) (RoomUUID, error)](#func-ed25519-createroom)
  * [func (ed25519 Ed25519) DerivePrivateKeyFromSpriv(spriv string, derivationPath \[\]uint32) (PrivateKey, error)](#func-ed25519-deriveprivatekeyfromspriv)
  * [func (ed25519 Ed25519) DerivePubkey(share Ed25519SecretShare, derivationPath \[\]uint32) (Ed25519PublicKey, error)](#func-ed25519-derivepubkey)
  * [func (ed25519 Ed25519) DerivePubkeyFromSpub(spub string, derivationPath \[\]uint32) (Ed25519PublicKey, error)](#func-ed25519-derivepubkeyfromspub)
  * [func (ed25519 Ed25519) ExportFullPrivateKey(roomUuid RoomUUID, share Ed25519SecretShare, toExportID KeygenID) (string, error)](#func-ed25519-exportfullprivatekey)
  * [func (ed25519 Ed25519) ExportID(share Ed25519SecretShare) (KeygenID, error)](#func-ed25519-exportid)
  * [func (ed25519 Ed25519) GetSpub(share Ed25519SecretShare) (string, error)](#func-ed25519-getspub)
  * [func (ed25519 Ed25519) ImportPrivateKeyImporter(roomUuid RoomUUID, threshold uint16, privateKey PrivateKey, keygenPrivateKey KeygenPrivateKey, keygenIDs \[\]KeygenID, optionalIsPrivateKeyRaw ...bool) (Ed25519SecretShare, Ed25519PublicKey, error)](#func-ed25519-importprivatekeyimporter)
  * [func (ed25519 Ed25519) ImportPrivateKeyRecipient(roomUuid RoomUUID, threshold uint16, keygenPrivateKey KeygenPrivateKey, keygenIDs \[\]KeygenID) (Ed25519SecretShare, Ed25519PublicKey, error)](#func-ed25519-importprivatekeyrecipient)
  * [func (ed25519 Ed25519) InitKeygen() (KeygenID, KeygenPrivateKey, error)](#func-ed25519-initkeygen)
  * [func (ed25519 Ed25519) Keygen(roomUuid RoomUUID, numParties uint16, threshold uint16, keygenPrivateKey KeygenPrivateKey, keygenIDs \[\]KeygenID) (Ed25519SecretShare, Ed25519PublicKey, error)](#func-ed25519-keygen)
  * [func (ed25519 Ed25519) OfflineExportFullPrivateKey(shares \[\]Ed25519SecretShare) (string, error)](#func-ed25519-offlineexportfullprivatekey)
  * [func (ed25519 Ed25519) Refresh(roomUuid RoomUUID, share Ed25519SecretShare) (Ed25519SecretShare, Ed25519PublicKey, error)](#func-ed25519-refresh)
  * [func (ed25519 Ed25519) ReshareNewParty(roomUuid RoomUUID, newThreshold uint16, keygenPrivateKey KeygenPrivateKey, keygenIDs \[\]KeygenID) (Ed25519SecretShare, Ed25519PublicKey, error)](#func-ed25519-resharenewparty)
  * [func (ed25519 Ed25519) ReshareRemainingParty(roomUuid RoomUUID, newThreshold uint16, share Ed25519SecretShare, keygenIDs \[\]KeygenID) (Ed25519SecretShare, Ed25519PublicKey, error)](#func-ed25519-reshareremainingparty)
  * [func (ed25519 Ed25519) Sign(roomUuid RoomUUID, share Ed25519SecretShare, msg \[\]byte, derivationPath \[\]uint32) (Ed25519Signature, error)](#func-ed25519-sign)
* [type Ed25519PublicKey](#type-ed25519publickey)
  * [func Ed25519PublicKeyFromString(s string) (Ed25519PublicKey, error)](#func-ed25519publickeyfromstring)
  * [func (pubkey \*Ed25519PublicKey) String() string](#func-ed25519publickey-string)
* [type Ed25519SecretShare](#type-ed25519secretshare)
  * [func (share Ed25519SecretShare) Bytes() \[\]byte](#func-ed25519secretshare-bytes)
* [type Ed25519Signature](#type-ed25519signature)
  * [func (sig \*Ed25519Signature) String() string](#func-ed25519signature-string)
* [type ExportableEd25519](#type-exportableed25519)
  * [func NewExportableEd25519(hostUrl string) ExportableEd25519](#func-newexportableed25519)
  * [func (exportableEd25519 ExportableEd25519) CreateRoom(numParties uint16, apiKey string) (RoomUUID, error)](#func-exportableed25519-createroom)
  * [func (exportableEd25519 ExportableEd25519) ExportFullPrivateKey(roomUuid RoomUUID, share ExportableEd25519SecretShare, toExportID KeygenID) (string, error)](#func-exportableed25519-exportfullprivatekey)
  * [func (exportableEd25519 ExportableEd25519) ExportID(share ExportableEd25519SecretShare) (KeygenID, error)](#func-exportableed25519-exportid)
  * [func (exportableEd25519 ExportableEd25519) GetPubkey(share ExportableEd25519SecretShare) (Ed25519PublicKey, error)](#func-exportableed25519-getpubkey)
  * [func (exportableEd25519 ExportableEd25519) ImportPrivateKeyImporter(roomUuid RoomUUID, threshold uint16, privateKey PrivateKey, keygenPrivateKey KeygenPrivateKey, keygenIDs \[\]KeygenID) (ExportableEd25519SecretShare, Ed25519PublicKey, error)](#func-exportableed25519-importprivatekeyimporter)
  * [func (exportableEd25519 ExportableEd25519) ImportPrivateKeyRecipient(roomUuid RoomUUID, threshold uint16, keygenPrivateKey KeygenPrivateKey, keygenIDs \[\]KeygenID) (ExportableEd25519SecretShare, Ed25519PublicKey, error)](#func-exportableed25519-importprivatekeyrecipient)
  * [func (exportableEd25519 ExportableEd25519) InitKeygen() (KeygenID, KeygenPrivateKey, error)](#func-exportableed25519-initkeygen)
  * [func (exportableEd25519 ExportableEd25519) OfflineExportFullPrivateKey(shares \[\]ExportableEd25519SecretShare) (string, error)](#func-exportableed25519-offlineexportfullprivatekey)
  * [func (exportableEd25519 ExportableEd25519) ReceiveKey(roomUuid RoomUUID, numParties uint16, threshold uint16, keygenPrivateKey KeygenPrivateKey, keygenIDs \[\]KeygenID) (ExportableEd25519SecretShare, Ed25519PublicKey, error)](#func-exportableed25519-receivekey)
  * [func (exportableEd25519 ExportableEd25519) Refresh(roomUuid RoomUUID, share ExportableEd25519SecretShare) (ExportableEd25519SecretShare, Ed25519PublicKey, error)](#func-exportableed25519-refresh)
  * [func (exportableEd25519 ExportableEd25519) ReshareNewParty(roomUuid RoomUUID, newThreshold uint16, keygenPrivateKey KeygenPrivateKey, keygenIDs \[\]KeygenID) (ExportableEd25519SecretShare, Ed25519PublicKey, error)](#func-exportableed25519-resharenewparty)
  * [func (exportableEd25519 ExportableEd25519) ReshareRemainingParty(roomUuid RoomUUID, newThreshold uint16, share ExportableEd25519SecretShare, keygenIDs \[\]KeygenID) (ExportableEd25519SecretShare, Ed25519PublicKey, error)](#func-exportableed25519-reshareremainingparty)
  * [func (exportableEd25519 ExportableEd25519) SampleKey(roomUuid RoomUUID, numParties uint16, threshold uint16, keygenPrivateKey KeygenPrivateKey, keygenIDs \[\]KeygenID) (ExportableEd25519SecretShare, Ed25519PublicKey, error)](#func-exportableed25519-samplekey)
  * [func (exportableEd25519 ExportableEd25519) Sign(roomUuid RoomUUID, share ExportableEd25519SecretShare, msg \[\]byte) (Ed25519Signature, error)](#func-exportableed25519-sign)
* [type ExportableEd25519SecretShare](#type-exportableed25519secretshare)
  * [func (share ExportableEd25519SecretShare) Bytes() \[\]byte](#func-exportableed25519secretshare-bytes)
* [type KeygenID](#type-keygenid)
* [type KeygenPrivateKey](#type-keygenprivatekey)
  * [func (privkey KeygenPrivateKey) Bytes() \[\]byte](#func-keygenprivatekey-bytes)
* [type MessageHash](#type-messagehash)
  * [func MessageHashFromKeccak256(data \[\]byte) MessageHash](#func-messagehashfromkeccak256)
  * [func MessageHashFromSha256(data \[\]byte) MessageHash](#func-messagehashfromsha256)
  * [func MessageHashFromSha256d(data \[\]byte) MessageHash](#func-messagehashfromsha256d)
* [type PrivateKey](#type-privatekey)
  * [func (privkey PrivateKey) Bytes() \[\]byte](#func-privatekey-bytes)
* [type RoomUUID](#type-roomuuid)
  * [func (uuid RoomUUID) Bytes() \[\]byte](#func-roomuuid-bytes)
* [type Sr25519](#type-sr25519)
  * [func NewSr25519(hostUrl string) Sr25519](#func-newsr25519)
  * [func (sr25519 Sr25519) CreateRoom(numParties uint16, apiKey string) (RoomUUID, error)](#func-sr25519-createroom)
  * [func (sr25519 Sr25519) DerivePrivateKeyFromPrivateKey(privateKey PrivateKey, isPrivateKeyRaw bool, derivationPath \[\]string) (PrivateKey, error)](#func-sr25519-deriveprivatekeyfromprivatekey)
  * [func (sr25519 Sr25519) DerivePubkey(share Sr25519SecretShare, derivationPath \[\]string) (Sr25519PublicKey, error)](#func-sr25519-derivepubkey)
  * [func (sr25519 Sr25519) DerivePubkeyFromPubKey(pubkey Sr25519PublicKey, derivationPath \[\]string) (Sr25519PublicKey, error)](#func-sr25519-derivepubkeyfrompubkey)
  * [func (sr25519 Sr25519) ExportFullPrivateKey(roomUuid RoomUUID, share Sr25519SecretShare, toExportID KeygenID) (string, error)](#func-sr25519-exportfullprivatekey)
  * [func (sr25519 Sr25519) ExportID(share Sr25519SecretShare) (KeygenID, error)](#func-sr25519-exportid)
  * [func (sr25519 Sr25519) GetPubKey(share Sr25519SecretShare) (Sr25519PublicKey, error)](#func-sr25519-getpubkey)
  * [func (sr25519 Sr25519) ImportPrivateKeyImporter(roomUuid RoomUUID, threshold uint16, privateKey PrivateKey, keygenPrivateKey KeygenPrivateKey, keygenIDs \[\]KeygenID, isPrivateKeyRaw bool) (Sr25519SecretShare, Sr25519PublicKey, error)](#func-sr25519-importprivatekeyimporter)
  * [func (sr25519 Sr25519) ImportPrivateKeyRecipient(roomUuid RoomUUID, threshold uint16, keygenPrivateKey KeygenPrivateKey, keygenIDs \[\]KeygenID) (Sr25519SecretShare, Sr25519PublicKey, error)](#func-sr25519-importprivatekeyrecipient)
  * [func (sr25519 Sr25519) InitKeygen() (KeygenID, KeygenPrivateKey, error)](#func-sr25519-initkeygen)
  * [func (sr25519 Sr25519) Keygen(roomUuid RoomUUID, numParties uint16, threshold uint16, keygenPrivateKey KeygenPrivateKey, keygenIDs \[\]KeygenID) (Sr25519SecretShare, Sr25519PublicKey, error)](#func-sr25519-keygen)
  * [func (sr25519 Sr25519) OfflineExportFullPrivateKey(shares \[\]Sr25519SecretShare) (string, error)](#func-sr25519-offlineexportfullprivatekey)
  * [func (sr25519 Sr25519) Refresh(roomUuid RoomUUID, share Sr25519SecretShare) (Sr25519SecretShare, Sr25519PublicKey, error)](#func-sr25519-refresh)
  * [func (sr25519 Sr25519) ReshareNewParty(roomUuid RoomUUID, newThreshold uint16, keygenPrivateKey KeygenPrivateKey, keygenIDs \[\]KeygenID) (Sr25519SecretShare, Sr25519PublicKey, error)](#func-sr25519-resharenewparty)
  * [func (sr25519 Sr25519) ReshareRemainingParty(roomUuid RoomUUID, newThreshold uint16, share Sr25519SecretShare, keygenIDs \[\]KeygenID) (Sr25519SecretShare, Sr25519PublicKey, error)](#func-sr25519-reshareremainingparty)
  * [func (sr25519 Sr25519) Sign(roomUuid RoomUUID, share Sr25519SecretShare, msg \[\]byte, derivationPath \[\]string) (Sr25519Signature, error)](#func-sr25519-sign)
* [type Sr25519PublicKey](#type-sr25519publickey)
  * [func Sr25519PublicKeyFromString(s string) (Sr25519PublicKey, error)](#func-sr25519publickeyfromstring)
  * [func (pubkey \*Sr25519PublicKey) String() string](#func-sr25519publickey-string)
* [type Sr25519SecretShare](#type-sr25519secretshare)
  * [func (share Sr25519SecretShare) Bytes() \[\]byte](#func-sr25519secretshare-bytes)
* [type Sr25519Signature](#type-sr25519signature)
  * [func (sig \*Sr25519Signature) String() string](#func-sr25519signature-string)

## Constants

<a name="SODOT_RELAY_URL" />

```
const SODOT_RELAY_URL = "us1.sodot.dev"
```

<a name="BIP340" />

## type BIP340

Class providing the functionality for the BIP340 protocol via the FROST MPC protocol.

```
type BIP340 struct {
    HostUrl string
}
```

<a name="NewBIP340" />

### func NewBIP340

```
func NewBIP340(hostUrl string) BIP340
```

NewBIP340 creates a new BIP340 instance

host URL to use, if "" is passed, the default host url(`SODOT_RELAY_URL`) will be used

<a name="BIP340.CreateRoom" />

### func (BIP340) CreateRoom

```
func (bip340 BIP340) CreateRoom(numParties uint16, apiKey string) (RoomUUID, error)
```

Creates a room for the given number of parties. A room is a one time instance used to perform a single MPC operation(keygen/signing/refresh etc.) between parties.

This function should be called in the backend so to not embed the API key in code that is distributed to the users. After the backend calls this function, the other parties can join the room by calling the relevant keygen/signing/refresh/etc. operation.

Returns a [RoomUUID](#type-roomuuid) of the created room.

<a name="BIP340.DerivePrivateKeyFromXpriv" />

### func (BIP340) DerivePrivateKeyFromXpriv

```
func (bip340 BIP340) DerivePrivateKeyFromXpriv(xpriv string, derivationPath []uint32) (PrivateKey, error)
```

Parses an `xpriv` string according to BIP-32 non-hardened, and returns the derived private key for a given BIP-32 non-hardened derivation path `xpriv` must be a valid secp256k1 xpriv string.

<a name="BIP340.DeriveTweakPubkey" />

### func (BIP340) DeriveTweakPubkey

```
func (bip340 BIP340) DeriveTweakPubkey(share BIP340SecretShare, derivationPath []uint32, tweak *[32]byte) (BIP340PublicKey, error)
```

Returns the (optionally)derived and (optionally)tweaked public key for a `keygenResult` for a given BIP-32 non-hardened derivation path and an optional BIP-341 tweak

The `tweak` is used to tweak a public key with a BIP-341 Taproot tweaking, by supplying the `T` value from the BIP-341 Taproot specification(https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki#script-validation-rules):

Let t = hash\_\{TapTweak}(p || km).

If t ≥ 0xFFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141 (order of secp256k1), fail.

Let Q = P + int(t)G.

<a name="BIP340.DeriveTweakPubkeyFromXpub" />

### func (BIP340) DeriveTweakPubkeyFromXpub

```
func (bip340 BIP340) DeriveTweakPubkeyFromXpub(xpub string, derivationPath []uint32, tweak *[32]byte) (BIP340PublicKey, error)
```

DeriveTweakPubkeyFromXpub derives a BIP340 public key from an extended public key (Xpub) using the provided derivation path and an optional 32-byte tweak. Returns the derived public key or an error on failure.

<a name="BIP340.ExportFullPrivateKey" />

### func (BIP340) ExportFullPrivateKey

```
func (bip340 BIP340) ExportFullPrivateKey(roomUuid RoomUUID, share BIP340SecretShare, toExportID KeygenID) (string, error)
```

Combine all [BIP340SecretShare](#type-bip340secretshare)-s and export the full private key to a single party. Requires a threshold amount of parties to participate. `toExportID` specifies the [KeygenID](#type-keygenid) of the party that should receive the private key, all parties must provide the same [KeygenID](#type-keygenid) or else export will fail.

The party being exported to will receive a `string` containing the full `xpriv`, while the rest will receive an empty string.

<a name="BIP340.ExportID" />

### func (BIP340) ExportID

```
func (bip340 BIP340) ExportID(share BIP340SecretShare) (KeygenID, error)
```

Extracts the [KeygenID](#type-keygenid) from an [BIP340SecretShare](#type-bip340secretshare). Useful for reshare operations.

<a name="BIP340.GetXpub" />

### func (BIP340) GetXpub

```
func (bip340 BIP340) GetXpub(share BIP340SecretShare) (string, error)
```

GetXpub returns a base58 encoded extended public key (Xpub, See \[BIP-32] for more details) derived from a [BIP340SecretShare](#type-bip340secretshare). The Xpub can be used either via third party libraries or via [BIP340.DeriveTweakPubkeyFromXpub](#func-bip340-derivetweakpubkeyfromxpub) \[BIP-32]: https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki#serialization-format

<a name="BIP340.ImportPrivateKeyImporter" />

### func (BIP340) ImportPrivateKeyImporter

```
func (bip340 BIP340) ImportPrivateKeyImporter(roomUuid RoomUUID, threshold uint16, privateKey PrivateKey, keygenPrivateKey KeygenPrivateKey, keygenIDs []KeygenID) (BIP340SecretShare, BIP340PublicKey, error)
```

WARNING: Private key import is an **advanced** feature of the SDK. We strongly advise consulting with the Sodot team **before** using it, due to a full private key being imported from a different system. Secret shares generated from imported private keys will always have the risk of the private key having been compromised in the past or in the future in case the private key is not deleted after the import operation.

Importing a **full private key**, and sharing into a `T-of-N` sharing, the resultant key shares will be of the exact **same** public key as the full private key.

This is the method that an importing party (meaning one the party in possesion of the private key) should use for receiving a key share in the new `T-of-N` quorum.

NOTE: `optionalIsPrivateKeyRaw` is an optional parameter with a default value of false. It should be set to true if `privateKey` is a raw private key and not an RFC 8032 encoded secret key. This will only be the case when manually creating this private key data, in case of importing from a standard BIP340 system this won't be the case and can be left as the default false value.

Returns an [BIP340SecretShare](#type-bip340secretshare) with the **secret** data that can be used for signing as well as the [BIP340PublicKey](#type-bip340publickey).

<a name="BIP340.ImportPrivateKeyRecipient" />

### func (BIP340) ImportPrivateKeyRecipient

```
func (bip340 BIP340) ImportPrivateKeyRecipient(roomUuid RoomUUID, threshold uint16, keygenPrivateKey KeygenPrivateKey, keygenIDs []KeygenID) (BIP340SecretShare, BIP340PublicKey, error)
```

WARNING: Private key import is an **advanced** feature of the SDK. We strongly advise consulting with the Sodot team **before** using it, due to a full private key being imported from a different system. Secret shares generated from imported private keys will always have the risk of the private key having been compromised in the past or in the future in case the private key is not deleted after the import operation.

Importing a **full private key**, and sharing into a `T-of-N` sharing, the resultant key shares will be of the exact **same** public key as the full private key.

This is the method that a new party (meaning one that does not currently have the private key) should use for receiving a key share in the new `T-of-N` quorum. The method takes the same input parameters as [BIP340.Keygen](#func-bip340-keygen) since for a new party joining the quorum the `Import` operation is very similar to a `Keygen` operation.

Returns an [BIP340SecretShare](#type-bip340secretshare) with the **secret** data that can be used for signing as well as the [BIP340PublicKey](#type-bip340publickey).

<a name="BIP340.InitKeygen" />

### func (BIP340) InitKeygen

```
func (bip340 BIP340) InitKeygen() (KeygenID, KeygenPrivateKey, error)
```

All parties must call this function **before** calling Keygen. All parties receive a ([KeygenID](#type-keygenid), [KeygenPrivateKey](#type-keygenprivatekey)) as an output from this function. The [KeygenID](#type-keygenid) must be sent through an authenticated communication channel to all other devices we wish to perform [BIP340.Keygen](#func-bip340-keygen) with. Once we have the [KeygenID](#type-keygenid)-s of all parties, then [BIP340.Keygen](#func-bip340-keygen) can be called with the **same** [KeygenPrivateKey](#type-keygenprivatekey) as was returned here.

<a name="BIP340.Keygen" />

### func (BIP340) Keygen

```
func (bip340 BIP340) Keygen(roomUuid RoomUUID, numParties uint16, threshold uint16, keygenPrivateKey KeygenPrivateKey, keygenIDs []KeygenID) (BIP340SecretShare, BIP340PublicKey, error)
```

Generate a keypair for the given number of parties and threshold.

:::warning[Notice]
`keygenPrivateKey` should be discarded after the successful completion of calling this function.
:::

Requires configuring the `threshold` and total number of participants (`numParties`) who will hold a secret share. This party's [KeygenPrivateKey](#type-keygenprivatekey) must be provided as well as an array of [KeygenID](#type-keygenid)-s (created using [BIP340.InitKeygen](#func-bip340-initkeygen)) received from all other parties we wish to share the keypair with.

Returns an [BIP340PublicKey](#type-bip340publickey) and an [BIP340SecretShare](#type-bip340secretshare) that contains the public key as well as the **secret** data that can be used for signing.

<a name="BIP340.OfflineExportFullPrivateKey" />

### func (BIP340) OfflineExportFullPrivateKey

```
func (bip340 BIP340) OfflineExportFullPrivateKey(shares []BIP340SecretShare) (string, error)
```

Receives as input an array of `threshold` [BIP340SecretShare](#type-bip340secretshare)-s and locally computes the full private key (`xpriv`). The main use case for this function is in an offline recovery setting where [BIP340SecretShare](#type-bip340secretshare)-s are collected manually and used to recover the full private key on an air-gapped server/device.

Returns a string containing the full `xpriv`.

<a name="BIP340.Refresh" />

### func (BIP340) Refresh

```
func (bip340 BIP340) Refresh(roomUuid RoomUUID, share BIP340SecretShare) (BIP340SecretShare, BIP340PublicKey, error)
```

Used for refreshing the **secret** material of all parties without altering the public key at all. Takes an [BIP340SecretShare](#type-bip340secretshare) as input and returns a new one for the same public key but with fresh key material. Be careful to delete the [BIP340SecretShare](#type-bip340secretshare) given as input before it is certain that all devices have properly stored the fresh [BIP340SecretShare](#type-bip340secretshare) that is output. Note that the new [BIP340SecretShare](#type-bip340secretshare)-s may only be used with each other, attempting to use older [BIP340SecretShare](#type-bip340secretshare)-s with newer ones for signing will result in failure.

The motivation for using refresh is to enhance security by switching the secret key material frequently, this means that an adversary will need to compromise multiple devices **at the same time** in order to compromise the private key.

<a name="BIP340.ReshareNewParty" />

### func (BIP340) ReshareNewParty

```
func (bip340 BIP340) ReshareNewParty(roomUuid RoomUUID, newThreshold uint16, keygenPrivateKey KeygenPrivateKey, keygenIDs []KeygenID) (BIP340SecretShare, BIP340PublicKey, error)
```

WARNING: Key resharing is an **advanced** feature of the SDK. We strongly advise consulting with the Sodot team **before** using it, as incorrect usage might lead to the **detriment** of the private key **security**. To use the feature correctly, developers using this feature must make sure that at least `n - t + 1` parties of the `t-of-n` signing quorum delete their current shares before using the resharing of the private key. Also, after resharing, the resharing operation must not be considered complete until such deletion has occurred. Since deleting a share **cannot** be guaranteed cryptographically, it **must** be guaranteed by the software architecture (hence, by the developers using the SDK).

Resharing the **private key** of the `t-of-n` quorum of signers, the resultant key shares will be of the exact **same** public key as the previous quorum. Resharing should be used in cases where we aim to modify the current `t-of-n` quorum with a new quorum with `newT-of-newN` signers for the same public key.

This is the method that a new party (meaning one that does not currently have an [BIP340SecretShare](#type-bip340secretshare) ) should use for receiving a key share in the new `newT-of-newN` quorum. The method takes the same input parameters as [BIP340.Keygen](#func-bip340-keygen) since for a new party joining the quorum the `Reshare` operation is very similar to a `Keygen` operation. In order to receive the [KeygenID](#type-keygenid)-s of parties that are already a part of the quorum, those parties will need to call \[ExportID] and send the result to the parties in the new quorum.

Returns an [BIP340SecretShare](#type-bip340secretshare) with the **secret** data that can be used for signing as well as the [BIP340PublicKey](#type-bip340publickey).

<a name="BIP340.ReshareRemainingParty" />

### func (BIP340) ReshareRemainingParty

```
func (bip340 BIP340) ReshareRemainingParty(roomUuid RoomUUID, newThreshold uint16, share BIP340SecretShare, keygenIDs []KeygenID) (BIP340SecretShare, BIP340PublicKey, error)
```

WARNING: Key resharing is an **advanced** feature of the SDK. We strongly advise consulting with the Sodot team **before** using it, as incorrect usage might lead to the **detriment** of the private key **security**. To use the feature correctly, developers using this feature must make sure that at least `n - t + 1` parties of the `t-of-n` signing quorum delete their current shares before using the resharing of the private key. Also, after resharing, the resharing operation must not be considered complete until such deletion has occurred. Since deleting a share **cannot** be guaranteed cryptographically, it **must** be guaranteed by the software architecture (hence, by the developers using the SDK).

Resharing the **private key** of the `t-of-n` quorum of signers, the resultant key shares will be of the exact **same** public key as the previous quorum. Resharing should be used in cases where we aim to modify the current `t-of-n` quorum with a new quorum with `newT-of-newN` signers for the same public key.

This is the method that a remaining party (meaning one that does currently have a key share) should use for receiving a new key share in the new `newT-of-newN` quorum. The method takes the same input parameters as [BIP340.ReshareNewParty](#func-bip340-resharenewparty) except that it will use its existing [BIP340SecretShare](#type-bip340secretshare) instead of a new [KeygenPrivateKey](#type-keygenprivatekey). In order to receive the [KeygenID](#type-keygenid)-s of parties that are already a part of the quorum, those parties will need to call \[ExportID] and send the result to the parties in the new quorum.

Returns a new [BIP340SecretShare](#type-bip340secretshare) with the **secret** data that can be used for signing as well as the [BIP340PublicKey](#type-bip340publickey).

<a name="BIP340.Sign" />

### func (BIP340) Sign

```
func (bip340 BIP340) Sign(roomUuid RoomUUID, share BIP340SecretShare, msg []byte, derivationPath []uint32, tweak *[32]byte) (BIP340Signature, error)
```

Sign a message with an [BIP340SecretShare](#type-bip340secretshare) created using [BIP340.Keygen](#func-bip340-keygen). `derivationPath` must be a BIP-32 non-hardened derivation path to use for signing `msg`. `tweak` is an optional parameter to support BIP341 taproot tweaks, see [BIP340.DeriveTweakPubkey](#func-bip340-derivetweakpubkey).

Returns the signature of the message.

<a name="BIP340PublicKey" />

## type BIP340PublicKey

An BIP340 public key, generated by the [BIP340.Keygen](#func-bip340-keygen) function.

```
type BIP340PublicKey [32]byte
```

<a name="BIP340PublicKeyFromString" />

### func BIP340PublicKeyFromString

```
func BIP340PublicKeyFromString(s string) (BIP340PublicKey, error)
```

BIP340PublicKeyFromString parses a hex string into an BIP340PublicKey.

<a name="BIP340PublicKey.String" />

### func (\*BIP340PublicKey) String

```
func (pubkey *BIP340PublicKey) String() string
```

String returns the hex representation of the public key.

<a name="BIP340SecretShare" />

## type BIP340SecretShare

The per-party **private** key material that is used for threshold signing

```
type BIP340SecretShare string
```

<a name="BIP340SecretShare.Bytes" />

### func (BIP340SecretShare) Bytes

```
func (share BIP340SecretShare) Bytes() []byte
```

Bytes returns the raw representation of the BIP340SecretShare.

<a name="BIP340Signature" />

## type BIP340Signature

An BIP340 signature, generated by the [BIP340.Sign](#func-bip340-sign) function.

```
type BIP340Signature [64]byte
```

<a name="BIP340Signature.String" />

### func (\*BIP340Signature) String

```
func (sig *BIP340Signature) String() string
```

String returns the hex representation of the signature.

<a name="Ecdsa" />

## type Ecdsa

Class providing the functionality for the ECDSA protocol via the DKLs19 MPC protocol.

```
type Ecdsa struct {
    HostUrl string
}
```

###### Example

```

const N = 3
const T = 2
const API_KEY = "MY_API_KEY"

ecdsa := NewEcdsa(SODOT_TEST_RELAY_URL)
keygenRoomUuid, err := ecdsa.CreateRoom(N, API_KEY)
if err != nil {
	panic(err)
}
// All parties call initKeygen to get a KeygenID and a KeygenPrivateKey
keygenID, keygenPrivKey, err := ecdsa.InitKeygen()
if err != nil {
	panic(err)
}
// Send the keygenID to all other parties
_ = keygenID
// All parties receive the keygenIds from all other parties
keygenIds := []KeygenID{"keygenID1", "keygenID2"}
// All parties join the keygen room
secretShare, pk, err := ecdsa.Keygen(keygenRoomUuid, N, T, keygenPrivKey, keygenIds)
if err != nil {
	panic(err)
}
// The public key can now be used to verify signatures
_ = pk

// Pick the derivation path of the public key you want to sign for
derivationPath := []uint32{44, 60, 0, 0, 0}
// Get the public key for the derivation path
derivedPubKey, err := ecdsa.DerivePubkey(secretShare, derivationPath)
if err != nil {
	panic(err)
}
// The derived public key can now be used to verify signatures with the same derivation path
_ = derivedPubKey
// To sign a message, create a signing room on the server side, using your API_KEY
signingRoomUuid, err := ecdsa.CreateRoom(T, API_KEY)
if err != nil {
	panic(err)
}
// Hash the message
messageHash := MessageHashFromSha256([]byte("my message"))
// 2 parties join the signing room
signature, err := ecdsa.Sign(signingRoomUuid, secretShare, messageHash, derivationPath)
if err != nil {
	panic(err)
}
// This signature can now be verified against pubkey
_ = signature
// Refreshing the secret key material
// Your server creates a room for 3 parties
refreshRoomUuid, err := ecdsa.CreateRoom(N, API_KEY)
if err != nil {
	panic(err)
}
// All parties join the refresh room
// Note: the public key returned here is the same as the one returned by the keygen
refreshedShare, _, err := ecdsa.Refresh(refreshRoomUuid, secretShare)
if err != nil {
	panic(err)
}

// Signing using the new secret key material
// The room is again created by the server
signingRoomUuid2, err := ecdsa.CreateRoom(T, API_KEY)
if err != nil {
	panic(err)
}

messageHash2 := MessageHashFromSha256([]byte("my new message"))
signature2, err := ecdsa.Sign(signingRoomUuid2, refreshedShare, messageHash2, derivationPath)
if err != nil {
	panic(err)
}
// This signature can now be verified against pubkey
_ = signature2

```

<a name="NewEcdsa" />

### func NewEcdsa

```
func NewEcdsa(hostUrl string) Ecdsa
```

NewEcdsa creates a new Ecdsa instance

host URL to use, if "" is passed, the default host url(`SODOT_RELAY_URL`) will be used

<a name="Ecdsa.CreateRoom" />

### func (Ecdsa) CreateRoom

```
func (ecdsa Ecdsa) CreateRoom(numParties uint16, apiKey string) (RoomUUID, error)
```

Creates a room for the given number of parties. A room is a one time instance used to perform a single MPC operation(keygen/signing/refresh etc.) between parties.

This function should be called in the backend so to not embed the API key in code that is distributed to the users. After the backend calls this function, the other parties can join the room by calling the relevant keygen/signing/refresh/etc. operation.

Returns a [RoomUUID](#type-roomuuid) of the created room.

<a name="Ecdsa.DerivePrivateKeyFromXpriv" />

### func (Ecdsa) DerivePrivateKeyFromXpriv

```
func (ecdsa Ecdsa) DerivePrivateKeyFromXpriv(xpriv string, derivationPath []uint32) (PrivateKey, error)
```

Parses an `xpriv` string according to BIP-32 non-hardened, and returns the derived private key for a given BIP-32 non-hardened derivation path `xpriv` must be a valid secp256k1 xpriv string.

<a name="Ecdsa.DerivePubkey" />

### func (Ecdsa) DerivePubkey

```
func (ecdsa Ecdsa) DerivePubkey(share EcdsaSecretShare, derivationPath []uint32) (EcdsaPublicKey, error)
```

Returns the derived public key for a [EcdsaSecretShare](#type-ecdsasecretshare) for a given BIP-32 non-hardened derivation path.

<a name="Ecdsa.DerivePubkeyFromXpub" />

### func (Ecdsa) DerivePubkeyFromXpub

```
func (ecdsa Ecdsa) DerivePubkeyFromXpub(xpub string, derivationPath []uint32) (EcdsaPublicKey, error)
```

DerivePubkeyFromXpub derives an Ecdsa public key from the given extended public key (Xpub) using the specified derivation path. Returns the derived public key or an error on failure.

<a name="Ecdsa.ExportFullPrivateKey" />

### func (Ecdsa) ExportFullPrivateKey

```
func (ecdsa Ecdsa) ExportFullPrivateKey(roomUuid RoomUUID, share EcdsaSecretShare, toExportID KeygenID) (string, error)
```

Combine all [EcdsaSecretShare](#type-ecdsasecretshare)-s and export the full private key to a single party. Requires a threshold amount of parties to participate. `toExportID` specifies the [KeygenID](#type-keygenid) of the party that should receive the private key, all parties must provide the same [KeygenID](#type-keygenid) or else export will fail.

The party being exported to will receive a `string` containing the full `xpriv`, while the rest will receive an empty string.

<a name="Ecdsa.ExportID" />

### func (Ecdsa) ExportID

```
func (ecdsa Ecdsa) ExportID(share EcdsaSecretShare) (KeygenID, error)
```

Extracts the [KeygenID](#type-keygenid) from an [EcdsaSecretShare](#type-ecdsasecretshare). Useful for reshare operations.

<a name="Ecdsa.GetXpub" />

### func (Ecdsa) GetXpub

```
func (ecda Ecdsa) GetXpub(share EcdsaSecretShare) (string, error)
```

GetXpub returns a base58 encoded extended public key (Xpub, See \[BIP-32] for more details) derived from a [EcdsaSecretShare](#type-ecdsasecretshare). The Xpub can be used either via third party libraries or via [Ecdsa.DerivePubkeyFromXpub](#func-ecdsa-derivepubkeyfromxpub) \[BIP-32]: https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki#serialization-format

<a name="Ecdsa.ImportPrivateKeyImporter" />

### func (Ecdsa) ImportPrivateKeyImporter

```
func (ecdsa Ecdsa) ImportPrivateKeyImporter(roomUuid RoomUUID, threshold uint16, privateKey PrivateKey, keygenPrivateKey KeygenPrivateKey, keygenIDs []KeygenID) (EcdsaSecretShare, EcdsaPublicKey, error)
```

WARNING: Private key import is an **advanced** feature of the SDK. We strongly advise consulting with the Sodot team **before** using it, due to a full private key being imported from a different system. Secret shares generated from imported private keys will always have the risk of the private key having been compromised in the past or in the future in case the private key is not deleted after the import operation.

Importing a **full private key**, and sharing into a `T-of-N` sharing, the resultant key shares will be of the exact **same** public key as the full private key.

This is the method that an importing party (meaning one the party in possesion of the private key) should use for receiving a key share in the new `T-of-N` quorum.

Returns an [EcdsaSecretShare](#type-ecdsasecretshare) with the **secret** data that can be used for signing as well as the [EcdsaPublicKey](#type-ecdsapublickey).

###### Example

```

const N = 3
const T = 2
const API_KEY = "MY_API_KEY"
// A private key is created in some external system.
privateKey := PrivateKey("8b7683659ee5ba5f0e1329e290ea9a9f051794535df627739717a600a10bff92")
// Some time passes...
// Now this party wishes to be part of a new quorum of `2-of-3` sharing of the private key.
//
// The app server creates a room for N(= 3) parties.
ecdsa := NewEcdsa(SODOT_TEST_RELAY_URL)
importRoomUuid, err := ecdsa.CreateRoom(N, API_KEY)
if err != nil {
	panic(err)
}

// The other parties must join the import room using the `ImportPrivateKeyRecipient` method.
keygenID, keygenPrivKey, err := ecdsa.InitKeygen()
if err != nil {
	panic(err)
}
// This importing party will send its `KeygenID` to all other parties.
// This party will also receive the `KeygenID`s of all other parties of the new quorum.
keygenIds := []KeygenID{"keygenID1", keygenID, "keygenID3"} // Note that here we must include our own `KeygenID` as well, the order of the ids doesn't matter.

// Note: the public key returned here is the same as the public key of the imported key
newShare, _, err := ecdsa.ImportPrivateKeyImporter(importRoomUuid, T, privateKey, keygenPrivKey, keygenIds)
if err != nil {
	panic(err)
}
// newShare can now be used for signing under the T(= 2) threshold with the same public key
_ = newShare

```

<a name="Ecdsa.ImportPrivateKeyRecipient" />

### func (Ecdsa) ImportPrivateKeyRecipient

```
func (ecdsa Ecdsa) ImportPrivateKeyRecipient(roomUuid RoomUUID, threshold uint16, keygenPrivateKey KeygenPrivateKey, keygenIDs []KeygenID) (EcdsaSecretShare, EcdsaPublicKey, error)
```

WARNING: Private key import is an **advanced** feature of the SDK. We strongly advise consulting with the Sodot team **before** using it, due to a full private key being imported from a different system. Secret shares generated from imported private keys will always have the risk of the private key having been compromised in the past or in the future in case the private key is not deleted after the import operation.

Importing a **full private key**, and sharing into a `T-of-N` sharing, the resultant key shares will be of the exact **same** public key as the full private key.

This is the method that a new party (meaning one that does not currently have the private key) should use for receiving a key share in the new `T-of-N` quorum. The method takes the same input parameters as [Ecdsa.Keygen](#func-ecdsa-keygen) since for a new party joining the quorum the `Import` operation is very similar to a `Keygen` operation.

Returns an [EcdsaSecretShare](#type-ecdsasecretshare) with the **secret** data that can be used for signing as well as the [EcdsaPublicKey](#type-ecdsapublickey).

###### Example

```

const N = 3
const T = 2
const API_KEY = "MY_API_KEY"
// A private key is created in some external system.
// Some time passes...
// Now this party wishes to be part of a new quorum of `2-of-3` sharing of the private key.
//
// The app server creates a room for N(= 3) parties.
ecdsa := NewEcdsa(SODOT_TEST_RELAY_URL)
importRoomUuid, err := ecdsa.CreateRoom(N, API_KEY)
if err != nil {
	panic(err)
}

// The party with the private key must join the import room using the `ImportPrivateKeyImporter` method.
keygenID, keygenPrivKey, err := ecdsa.InitKeygen()
if err != nil {
	panic(err)
}
// This new party will send its `KeygenID` to all other parties.
// This party will also receive the `KeygenID`s of all other parties of the new quorum.
keygenIds := []KeygenID{"keygenID1", keygenID, "keygenID3"} // Note that here we must include our own `KeygenID` as well, the order of the ids doesn't matter.

// Note: the public key returned here is the same as the public key of the imported key
newShare, _, err := ecdsa.ImportPrivateKeyRecipient(importRoomUuid, T, keygenPrivKey, keygenIds)
if err != nil {
	panic(err)
}
// newShare can now be used for signing under the T(= 2) threshold with the same public key
_ = newShare

```

<a name="Ecdsa.InitKeygen" />

### func (Ecdsa) InitKeygen

```
func (ecdsa Ecdsa) InitKeygen() (KeygenID, KeygenPrivateKey, error)
```

All parties must call this function **before** calling Keygen. All parties receive a ([KeygenID](#type-keygenid), [KeygenPrivateKey](#type-keygenprivatekey)) as an output from this function. The [KeygenID](#type-keygenid) must be sent through an authenticated communication channel to all other devices we wish to perform [Ecdsa.Keygen](#func-ecdsa-keygen) with. Once we have the [KeygenID](#type-keygenid)-s of all parties, then [Ecdsa.Keygen](#func-ecdsa-keygen) can be called with the **same** [KeygenPrivateKey](#type-keygenprivatekey) as was returned here.

<a name="Ecdsa.Keygen" />

### func (Ecdsa) Keygen

```
func (ecdsa Ecdsa) Keygen(roomUuid RoomUUID, numParties uint16, threshold uint16, keygenPrivateKey KeygenPrivateKey, keygenIDs []KeygenID) (EcdsaSecretShare, EcdsaPublicKey, error)
```

Generate a keypair for the given number of parties and threshold.

:::warning[Notice]
`keygenPrivateKey` should be discarded after the successful completion of calling this function.
:::

Requires configuring the `threshold` and total number of participants (`numParties`) who will hold a secret share. This party's [KeygenPrivateKey](#type-keygenprivatekey) must be provided as well as an array of [KeygenID](#type-keygenid)-s (created using [Ecdsa.InitKeygen](#func-ecdsa-initkeygen)) received from all other parties we wish to share the keypair with.

Returns a [EcdsaSecretShare](#type-ecdsasecretshare) and an [EcdsaPublicKey](#type-ecdsapublickey) that contains the public key as well as the **secret** data that can be used for signing.

###### Example

```

// Your server side creates a room for 3 parties using its API_KEY
// Creating a room uuid should always happen on the server side using your API_KEY
const N = 3
const T = 2
const API_KEY = "MY_API_KEY"

ecdsa := NewEcdsa(SODOT_TEST_RELAY_URL)
keygenRoomUuid, err := ecdsa.CreateRoom(N, API_KEY)
if err != nil {
	panic(err)
}
// All parties call initKeygen to get a KeygenID and a KeygenPrivateKey
keygenID, keygenPrivKey, err := ecdsa.InitKeygen()
if err != nil {
	panic(err)
}
// Send the keygenID to all other parties
_ = keygenID
// All parties receive the keygenIds from all other parties
keygenIds := []KeygenID{"keygenID1", "keygenID2"}
// All parties join the keygen room
secretShare, pk, err := ecdsa.Keygen(keygenRoomUuid, N, T, keygenPrivKey, keygenIds)
if err != nil {
	panic(err)
}
// The public key can now be used to verify signatures
_, _ = secretShare, pk

```

<a name="Ecdsa.OfflineExportFullPrivateKey" />

### func (Ecdsa) OfflineExportFullPrivateKey

```
func (ecdsa Ecdsa) OfflineExportFullPrivateKey(shares []EcdsaSecretShare) (string, error)
```

Receives as input an array of `threshold` [EcdsaSecretShare](#type-ecdsasecretshare)-s and locally computes the full private key (`xpriv`). The main use case for this function is in an offline recovery setting where [EcdsaSecretShare](#type-ecdsasecretshare)-s are collected manually and used to recover the full private key on an air-gapped server/device.

Returns a string containing the full `xpriv`.

<a name="Ecdsa.Refresh" />

### func (Ecdsa) Refresh

```
func (ecdsa Ecdsa) Refresh(roomUuid RoomUUID, share EcdsaSecretShare) (EcdsaSecretShare, EcdsaPublicKey, error)
```

Used for refreshing the **secret** material of all parties without altering the public key at all. Takes an [EcdsaSecretShare](#type-ecdsasecretshare) as input and returns a new one for the same public key but with fresh key material. Be careful to delete the [EcdsaSecretShare](#type-ecdsasecretshare) given as input before it is certain that all devices have properly stored the fresh [EcdsaSecretShare](#type-ecdsasecretshare) that is output. Note that the new [EcdsaSecretShare](#type-ecdsasecretshare)-s may only be used with each other, attempting to use older [EcdsaSecretShare](#type-ecdsasecretshare)-s with newer ones for signing will result in failure.

The motivation for using refresh is to enhance security by switching the secret key material frequently, this means that an adversary will need to compromise multiple devices **at the same time** in order to compromise the private key.

###### Example

```

const N = 3
const API_KEY = "MY_API_KEY"
// An EcdsaSecretShare is generated using Keygen
// secretShare, pk, err := ecdsa.Keygen(...)
var secretShare EcdsaSecretShare
// Some time passes ...
// We now refresh the secret key material of our public key
ecdsa := NewEcdsa(SODOT_TEST_RELAY_URL)
refreshRoomUuid, err := ecdsa.CreateRoom(N, API_KEY)
if err != nil {
	panic(err)
}

// Note: the public key returned here is the same as the one returned by the keygen
_, refreshedShare, err := ecdsa.Refresh(refreshRoomUuid, secretShare)
if err != nil {
	panic(err)
}
// refreshedShare can now be used for signing under the same T threshold, as well as be refreshed again
_ = refreshedShare

```

<a name="Ecdsa.ReshareNewParty" />

### func (Ecdsa) ReshareNewParty

```
func (ecdsa Ecdsa) ReshareNewParty(roomUuid RoomUUID, newThreshold uint16, keygenPrivateKey KeygenPrivateKey, keygenIDs []KeygenID) (EcdsaSecretShare, EcdsaPublicKey, error)
```

WARNING: Key resharing is an **advanced** feature of the SDK. We strongly advise consulting with the Sodot team **before** using it, as incorrect usage might lead to the **detriment** of the private key **security**. To use the feature correctly, developers using this feature must make sure that at least `n - t + 1` parties of the `t-of-n` signing quorum delete their current shares before using the resharing of the private key. Also, after resharing, the resharing operation must not be considered complete until such deletion has occurred. Since deleting a share **cannot** be guaranteed cryptographically, it **must** be guaranteed by the software architecture (hence, by the developers using the SDK).

Resharing the **private key** of the `t-of-n` quorum of signers, the resultant key shares will be of the exact **same** public key as the previous quorum. Resharing should be used in cases where we aim to modify the current `t-of-n` quorum with a new quorum with `newT-of-newN` signers for the same public key.

This is the method that a new party (meaning one that does not currently have an [EcdsaSecretShare](#type-ecdsasecretshare) ) should use for receiving a key share in the new `newT-of-newN` quorum. The method takes the same input parameters as [Ecdsa.Keygen](#func-ecdsa-keygen) since for a new party joining the quorum the `Reshare` operation is very similar to a `Keygen` operation. In order to receive the [KeygenID](#type-keygenid)-s of parties that are already a part of the quorum, those parties will need to call \[ExportID] and send the result to the parties in the new quorum.

Returns an [EcdsaSecretShare](#type-ecdsasecretshare) with the **secret** data that can be used for signing as well as the [EcdsaPublicKey](#type-ecdsapublickey).

###### Example

```

const N = 5
const newT = 5
const API_KEY = "MY_API_KEY"
// A signing quorum of `3-of-5` is set up without this party.
// Some time passes...
// Now this party wishes to be part of a new quorum of `5-of-6`.
//
// The app server creates a room for newN(= 6) parties.
ecdsa := NewEcdsa(SODOT_TEST_RELAY_URL)
reshareRoomUuid, err := ecdsa.CreateRoom(N, API_KEY)
if err != nil {
	panic(err)
}

// At least T(= 3) parties now join the reshare room using the current secret key material (this will be done using `ReshareRemainingParty`), all new parties will then join the reshare room using their `KeygenPrivateKey` using `ReshareNewParty`.
keygenID, keygenPrivKey, err := ecdsa.InitKeygen()
if err != nil {
	panic(err)
}
// This new party will send its `KeygenID` to all other parties.
// This party will also receive the `KeygenID`s of all other parties of the new quorum.
keygenIds := []KeygenID{"keygenID1", keygenID, "keygenID3", "keygenID4", "keygenID5", "keygenID6"} // Note that here we must include our own `KeygenID` as well, the order of the ids doesn't matter.

// Note: the public key returned here is the same as the one returned by the keygen
newShare, _, err := ecdsa.ReshareNewParty(reshareRoomUuid, newT, keygenPrivKey, keygenIds)
if err != nil {
	panic(err)
}
// newShare can now be used for signing under the newT(= 5) threshold with the same public key, as well as be reshared again
_ = newShare

```

<a name="Ecdsa.ReshareRemainingParty" />

### func (Ecdsa) ReshareRemainingParty

```
func (ecdsa Ecdsa) ReshareRemainingParty(roomUuid RoomUUID, newThreshold uint16, share EcdsaSecretShare, keygenIDs []KeygenID) (EcdsaSecretShare, EcdsaPublicKey, error)
```

WARNING: Key resharing is an **advanced** feature of the SDK. We strongly advise consulting with the Sodot team **before** using it, as incorrect usage might lead to the **detriment** of the private key **security**. To use the feature correctly, developers using this feature must make sure that at least `n - t + 1` parties of the `t-of-n` signing quorum delete their current shares before using the resharing of the private key. Also, after resharing, the resharing operation must not be considered complete until such deletion has occurred. Since deleting a share **cannot** be guaranteed cryptographically, it **must** be guaranteed by the software architecture (hence, by the developers using the SDK).

Resharing the **private key** of the `t-of-n` quorum of signers, the resultant key shares will be of the exact **same** public key as the previous quorum. Resharing should be used in cases where we aim to modify the current `t-of-n` quorum with a new quorum with `newT-of-newN` signers for the same public key.

This is the method that a remaining party (meaning one that does currently have a key share) should use for receiving a new key share in the new `newT-of-newN` quorum. The method takes the same input parameters as [Ecdsa.ReshareNewParty](#func-ecdsa-resharenewparty) except that it will use its existing [EcdsaSecretShare](#type-ecdsasecretshare) instead of a new [KeygenPrivateKey](#type-keygenprivatekey). In order to receive the [KeygenID](#type-keygenid)-s of parties that are already a part of the quorum, those parties will need to call \[ExportID] and send the result to the parties in the new quorum.

Returns a new [EcdsaSecretShare](#type-ecdsasecretshare) with the **secret** data that can be used for signing as well as the [EcdsaPublicKey](#type-ecdsapublickey).

###### Example

```

const N = 5
const newT = 5
const API_KEY = "MY_API_KEY"
// A signing quorum of `3-of-5` is set up with this party.
// secretShare, pk, err := ecdsa.Keygen(...)
var secretShare EcdsaSecretShare
//
// Some time passes...
// Now this party wishes to be part of a new quorum of `5-of-6`.
//
// The app server creates a room for newN(= 6) parties.
ecdsa := NewEcdsa(SODOT_TEST_RELAY_URL)
reshareRoomUuid, err := ecdsa.CreateRoom(N, API_KEY)
if err != nil {
	panic(err)
}

// At least T(= 3) parties now join the reshare room using the current secret key material (this will be done using `ReshareRemainingParty`), all new parties will then join the reshare room using their `KeygenPrivateKey` using `ReshareNewParty`.
keygenID, err := ecdsa.ExportID(secretShare) // This is a remaining party
if err != nil {
	panic(err)
}

// This remaining party will send its `KeygenID` to all other parties (new - via an authenticated channel and remaining - via any channel).
// This party will also receive the `KeygenID`s of all other parties of the new quorum (new - via an authenticated channel and remaining - via any channel).
keygenIds := []KeygenID{"keygenID1", "keygenID2", keygenID, "keygenID4", "keygenID5", "keygenID6"} // Note that here we must include our own `KeygenID` as well, the order of the ids doesn't matter.

// Note: the public key returned here is the same as the one returned by the keygen
newShare, _, err := ecdsa.ReshareRemainingParty(reshareRoomUuid, newT, secretShare, keygenIds)
if err != nil {
	panic(err)
}
// newShare can now be used for signing under the newT(= 5) threshold with the same public key, as well as be reshared again
_ = newShare

```

<a name="Ecdsa.Sign" />

### func (Ecdsa) Sign

```
func (ecdsa Ecdsa) Sign(roomUuid RoomUUID, share EcdsaSecretShare, msgHash MessageHash, derivationPath []uint32) (EcdsaSignature, error)
```

Sign a message with an [EcdsaSecretShare](#type-ecdsasecretshare) created using [Ecdsa.Keygen](#func-ecdsa-keygen). The message must be hashed before signing, this can be done using the [MessageHash](#type-messagehash) type. `derivationPath` must be a BIP-32 non-hardened derivation path to use for signing `msgHash`.

Returns the signature of the message.

###### Example

```

// To sign a message, create a signing room on the server side, using your API_KEY
const T = 2
const API_KEY = "MY_API_KEY"
// An EcdsaSecretShare is generated using Keygen
// secretShare, pk, err := ecdsa.Keygen(...)
var secretShare EcdsaSecretShare
ecdsa := NewEcdsa(SODOT_TEST_RELAY_URL)
signingRoomUuid, err := ecdsa.CreateRoom(T, API_KEY)
if err != nil {
	panic(err)
}

// Pick the derivation path of the public key you want to sign for
derivationPath := []uint32{44, 60, 0, 0, 0}
// Get the public key for the derivation path
derivedPubKey, err := ecdsa.DerivePubkey(secretShare, derivationPath)
if err != nil {
	panic(err)
}
// The derived public key can now be used to verify signatures with the same derivation path
_ = derivedPubKey

// Hash the message
messageHash := MessageHashFromSha256([]byte("my message"))
// 2 parties join the signing room
signature, err := ecdsa.Sign(signingRoomUuid, secretShare, messageHash, derivationPath)
if err != nil {
	panic(err)
}
// This signature can now be verified against pubkey
_ = signature

```

<a name="EcdsaPublicKey" />

## type EcdsaPublicKey

An ECDSA public key, generated by the [Ecdsa.Keygen](#func-ecdsa-keygen) function. You can get the compressed form (33 bytes) via the [EcdsaPublicKey.SerializeCompressed](#func-ecdsapublickey-serializecompressed) function, or the uncompressed form (65 bytes) via the [EcdsaPublicKey.SerializeUncompressed](#func-ecdsapublickey-serializeuncompressed) function.

```
type EcdsaPublicKey [65]byte
```

<a name="EcdsaPublicKeyFromString" />

### func EcdsaPublicKeyFromString

```
func EcdsaPublicKeyFromString(s string) (EcdsaPublicKey, error)
```

<a name="EcdsaPublicKey.Equal" />

### func (\*EcdsaPublicKey) Equal

```
func (pubkey *EcdsaPublicKey) Equal(other EcdsaPublicKey) bool
```

Equal returns true if the two public keys are equal.

<a name="EcdsaPublicKey.SerializeCompressed" />

### func (\*EcdsaPublicKey) SerializeCompressed

```
func (pubkey *EcdsaPublicKey) SerializeCompressed() (ret [33]byte)
```

SerializeCompressed returns the compressed public key as a \[33]byte .

<a name="EcdsaPublicKey.SerializeUncompressed" />

### func (\*EcdsaPublicKey) SerializeUncompressed

```
func (pubkey *EcdsaPublicKey) SerializeUncompressed() [65]byte
```

SerializeUncompressed returns the uncompressed public key as a \[65]byte .

<a name="EcdsaPublicKey.String" />

### func (\*EcdsaPublicKey) String

```
func (pubkey *EcdsaPublicKey) String() string
```

String returns the hex representation of the uncompressed public key.

<a name="EcdsaSecretShare" />

## type EcdsaSecretShare

The per-party **private** key material that is used for threshold signing

```
type EcdsaSecretShare string
```

<a name="EcdsaSecretShare.Bytes" />

### func (EcdsaSecretShare) Bytes

```
func (share EcdsaSecretShare) Bytes() []byte
```

<a name="EcdsaSignature" />

## type EcdsaSignature

An ECDSA signature, generated by the [Ecdsa.Sign](#func-ecdsa-sign) function. You can get the [DER](https://en.wikipedia.org/wiki/X.690#DER_encoding) encoded signature via the [EcdsaSignature.DER](#func-ecdsasignature-der) method, or the r,s,v form via the [EcdsaSignature.R](#func-ecdsasignature-r), [EcdsaSignature.S](#func-ecdsasignature-s) and [EcdsaSignature.V](#func-ecdsasignature-v) methods.

```
type EcdsaSignature struct {
    // contains filtered or unexported fields
}
```

<a name="EcdsaSignature.DER" />

### func (EcdsaSignature) DER

```
func (sig EcdsaSignature) DER() []byte
```

R returns the r value for an r,s,v encoding of an ECDSA signature.

<a name="EcdsaSignature.Equal" />

### func (EcdsaSignature) Equal

```
func (sig EcdsaSignature) Equal(other EcdsaSignature) bool
```

<a name="EcdsaSignature.R" />

### func (EcdsaSignature) R

```
func (sig EcdsaSignature) R() []byte
```

R returns the r value for an r,s,v encoding of an ECDSA signature.

<a name="EcdsaSignature.S" />

### func (EcdsaSignature) S

```
func (sig EcdsaSignature) S() []byte
```

S returns the s value for an r,s,v encoding of an ECDSA signature.

<a name="EcdsaSignature.String" />

### func (EcdsaSignature) String

```
func (sig EcdsaSignature) String() string
```

String returns the hex representation of the compact signature representation (r || s)

<a name="EcdsaSignature.V" />

### func (EcdsaSignature) V

```
func (sig EcdsaSignature) V() byte
```

V returns the v value for an r,s,v encoding of an ECDSA signature.

<a name="Ed25519" />

## type Ed25519

Class providing the functionality for the Ed25519 protocol via the FROST MPC protocol.

```
type Ed25519 struct {
    HostUrl string
}
```

###### Example

```

const N = 3
const T = 2
const API_KEY = "MY_API_KEY"

ed25519 := NewEd25519("")
keygenRoomUuid, err := ed25519.CreateRoom(N, API_KEY)
if err != nil {
	panic(err)
}
// All parties call initKeygen to get a KeygenID and a KeygenPrivateKey
keygenID, keygenPrivKey, err := ed25519.InitKeygen()
if err != nil {
	panic(err)
}
// Send the keygenID to all other parties
_ = keygenID
// All parties receive the keygenIds from all other parties
keygenIds := []KeygenID{"keygenID1", "keygenID2"}
// All parties join the keygen room
secretShare, pk, err := ed25519.Keygen(keygenRoomUuid, N, T, keygenPrivKey, keygenIds)
if err != nil {
	panic(err)
}
// The public key can now be used to verify signatures
_ = pk

// Pick the derivation path of the public key you want to sign for
derivationPath := []uint32{44, 60, 0, 0, 0}
// Get the public key for the derivation path
derivedPubKey, err := ed25519.DerivePubkey(secretShare, derivationPath)
if err != nil {
	panic(err)
}
// The derived public key can now be used to verify signatures with the same derivation path
_ = derivedPubKey
// To sign a message, create a signing room on the server side, using your API_KEY
signingRoomUuid, err := ed25519.CreateRoom(T, API_KEY)
if err != nil {
	panic(err)
}
// Define the message
message := []byte("my message")
// 2 parties join the signing room
signature, err := ed25519.Sign(signingRoomUuid, secretShare, message, derivationPath)
if err != nil {
	panic(err)
}
// This signature can now be verified against pubkey
_ = signature
// Refreshing the secret key material
// Your server creates a room for 3 parties
refreshRoomUuid, err := ed25519.CreateRoom(N, API_KEY)
if err != nil {
	panic(err)
}
// All parties join the refresh room
// Note: the public key returned here is the same as the one returned by the keygen
refreshedShare, _, err := ed25519.Refresh(refreshRoomUuid, secretShare)
if err != nil {
	panic(err)
}

// Signing using the new secret key material
// The room is again created by the server
signingRoomUuid2, err := ed25519.CreateRoom(T, API_KEY)
if err != nil {
	panic(err)
}

message2 := []byte("my new message")
signature2, err := ed25519.Sign(signingRoomUuid2, refreshedShare, message2, derivationPath)
if err != nil {
	panic(err)
}
// This signature can now be verified against pubkey
_ = signature2

```

<a name="NewEd25519" />

### func NewEd25519

```
func NewEd25519(hostUrl string) Ed25519
```

NewEd25519 creates a new Ed25519 instance

host URL to use, if "" is passed, the default host url(`SODOT_RELAY_URL`) will be used

<a name="Ed25519.CreateRoom" />

### func (Ed25519) CreateRoom

```
func (ed25519 Ed25519) CreateRoom(numParties uint16, apiKey string) (RoomUUID, error)
```

Creates a room for the given number of parties. A room is a one time instance used to perform a single MPC operation(keygen/signing/refresh etc.) between parties.

This function should be called in the backend so to not embed the API key in code that is distributed to the users. After the backend calls this function, the other parties can join the room by calling the relevant keygen/signing/refresh/etc. operation.

Returns a [RoomUUID](#type-roomuuid) of the created room.

<a name="Ed25519.DerivePrivateKeyFromSpriv" />

### func (Ed25519) DerivePrivateKeyFromSpriv

```
func (ed25519 Ed25519) DerivePrivateKeyFromSpriv(spriv string, derivationPath []uint32) (PrivateKey, error)
```

Parses an `spriv` string according to Sodot's non-hardened derivation, and returns the derived private key for a given BIP-32 non-hardened derivation path

<a name="Ed25519.DerivePubkey" />

### func (Ed25519) DerivePubkey

```
func (ed25519 Ed25519) DerivePubkey(share Ed25519SecretShare, derivationPath []uint32) (Ed25519PublicKey, error)
```

Returns the derived public key for a [Ed25519SecretShare](#type-ed25519secretshare) for a given BIP-32 non-hardened derivation path.

<a name="Ed25519.DerivePubkeyFromSpub" />

### func (Ed25519) DerivePubkeyFromSpub

```
func (ed25519 Ed25519) DerivePubkeyFromSpub(spub string, derivationPath []uint32) (Ed25519PublicKey, error)
```

DerivePubkeyFromXpub derives an Ecdsa public key from the given extended public key (Xpub) using the specified derivation path. Returns the derived public key or an error on failure.

<a name="Ed25519.ExportFullPrivateKey" />

### func (Ed25519) ExportFullPrivateKey

```
func (ed25519 Ed25519) ExportFullPrivateKey(roomUuid RoomUUID, share Ed25519SecretShare, toExportID KeygenID) (string, error)
```

Combine all [Ed25519SecretShare](#type-ed25519secretshare)-s and export the full private key to a single party. Requires a threshold amount of parties to participate. `toExportID` specifies the [KeygenID](#type-keygenid) of the party that should receive the private key, all parties must provide the same [KeygenID](#type-keygenid) or else export will fail.

The party being exported to will receive a `string` containing the full `spriv`, while the rest will receive an empty string.

<a name="Ed25519.ExportID" />

### func (Ed25519) ExportID

```
func (ed25519 Ed25519) ExportID(share Ed25519SecretShare) (KeygenID, error)
```

Extracts the [KeygenID](#type-keygenid) from an [Ed25519SecretShare](#type-ed25519secretshare). Useful for reshare operations.

<a name="Ed25519.GetSpub" />

### func (Ed25519) GetSpub

```
func (ed25519 Ed25519) GetSpub(share Ed25519SecretShare) (string, error)
```

GetSpub returns a base58 encoded extended public key (Spub) derived from a [Ed25519SecretShare](#type-ed25519secretshare). Note that unlike `ecdsa` or `bip340` there's no standardization for the extended public key format for Ed25519. so `S` stands for `Sodot`, and is a somewhat custom derivation scheme adapted for Ed25519. The Spub can be used via [Ed25519.DerivePubkeyFromSpub](#func-ed25519-derivepubkeyfromspub) \[BIP-32]: https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki#serialization-format

<a name="Ed25519.ImportPrivateKeyImporter" />

### func (Ed25519) ImportPrivateKeyImporter

```
func (ed25519 Ed25519) ImportPrivateKeyImporter(roomUuid RoomUUID, threshold uint16, privateKey PrivateKey, keygenPrivateKey KeygenPrivateKey, keygenIDs []KeygenID, optionalIsPrivateKeyRaw ...bool) (Ed25519SecretShare, Ed25519PublicKey, error)
```

WARNING: Private key import is an **advanced** feature of the SDK. We strongly advise consulting with the Sodot team **before** using it, due to a full private key being imported from a different system. Secret shares generated from imported private keys will always have the risk of the private key having been compromised in the past or in the future in case the private key is not deleted after the import operation.

Importing a **full private key**, and sharing into a `T-of-N` sharing, the resultant key shares will be of the exact **same** public key as the full private key.

This is the method that an importing party (meaning one the party in possesion of the private key) should use for receiving a key share in the new `T-of-N` quorum.

NOTE: `optionalIsPrivateKeyRaw` is an optional parameter with a default value of false. It should be set to true if `privateKey` is a raw private key and not an RFC 8032 encoded secret key. This will only be the case when manually creating this private key data, in case of importing from a standard Ed25519 system this won't be the case and can be left as the default false value.

Returns an [Ed25519SecretShare](#type-ed25519secretshare) with the **secret** data that can be used for signing as well as the [Ed25519PublicKey](#type-ed25519publickey).

###### Example

```

const N = 3
const T = 2
const API_KEY = "MY_API_KEY"
// A private key is created in some external system.
privateKey := PrivateKey("17b362b66ff82220f0d09f830c1aeaa52a42e85cae6d31c6c379d485103ba435")
// Some time passes...
// Now this party wishes to be part of a new quorum of `2-of-3` sharing of the private key.
//
// The app server creates a room for N(= 3) parties.
ed25519 := NewEd25519("")
importRoomUuid, err := ed25519.CreateRoom(N, API_KEY)
if err != nil {
	panic(err)
}

// The other parties must join the import room using the `ImportPrivateKeyRecipient` method.
keygenID, keygenPrivKey, err := ed25519.InitKeygen()
if err != nil {
	panic(err)
}
// This importing party will send its `KeygenID` to all other parties.
// This party will also receive the `KeygenID`s of all other parties of the new quorum.
keygenIds := []KeygenID{"keygenID1", keygenID, "keygenID3"} // Note that here we must include our own `KeygenID` as well, the order of the ids doesn't matter.

// Note: the public key returned here is the same as the public key of the imported key
newShare, _, err := ed25519.ImportPrivateKeyImporter(importRoomUuid, T, privateKey, keygenPrivKey, keygenIds)
if err != nil {
	panic(err)
}
// newShare can now be used for signing under the T(= 2) threshold with the same public key
_ = newShare

```

<a name="Ed25519.ImportPrivateKeyRecipient" />

### func (Ed25519) ImportPrivateKeyRecipient

```
func (ed25519 Ed25519) ImportPrivateKeyRecipient(roomUuid RoomUUID, threshold uint16, keygenPrivateKey KeygenPrivateKey, keygenIDs []KeygenID) (Ed25519SecretShare, Ed25519PublicKey, error)
```

WARNING: Private key import is an **advanced** feature of the SDK. We strongly advise consulting with the Sodot team **before** using it, due to a full private key being imported from a different system. Secret shares generated from imported private keys will always have the risk of the private key having been compromised in the past or in the future in case the private key is not deleted after the import operation.

Importing a **full private key**, and sharing into a `T-of-N` sharing, the resultant key shares will be of the exact **same** public key as the full private key.

This is the method that a new party (meaning one that does not currently have the private key) should use for receiving a key share in the new `T-of-N` quorum. The method takes the same input parameters as [Ed25519.Keygen](#func-ed25519-keygen) since for a new party joining the quorum the `Import` operation is very similar to a `Keygen` operation.

Returns an [Ed25519SecretShare](#type-ed25519secretshare) with the **secret** data that can be used for signing as well as the [Ed25519PublicKey](#type-ed25519publickey).

###### Example

```

const N = 3
const T = 2
const API_KEY = "MY_API_KEY"
// A private key is created in some external system.
// Some time passes...
// Now this party wishes to be part of a new quorum of `2-of-3` sharing of the private key.
//
// The app server creates a room for N(= 3) parties.
ed25519 := NewEd25519("")
importRoomUuid, err := ed25519.CreateRoom(N, API_KEY)
if err != nil {
	panic(err)
}

// The party with the private key must join the import room using the `ImportPrivateKeyImporter` method.
keygenID, keygenPrivKey, err := ed25519.InitKeygen()
if err != nil {
	panic(err)
}
// This new party will send its `KeygenID` to all other parties.
// This party will also receive the `KeygenID`s of all other parties of the new quorum.
keygenIds := []KeygenID{"keygenID1", keygenID, "keygenID3"} // Note that here we must include our own `KeygenID` as well, the order of the ids doesn't matter.

// Note: the public key returned here is the same as the public key of the imported key
newShare, _, err := ed25519.ImportPrivateKeyRecipient(importRoomUuid, T, keygenPrivKey, keygenIds)
if err != nil {
	panic(err)
}
// newShare can now be used for signing under the T(= 2) threshold with the same public key
_ = newShare

```

<a name="Ed25519.InitKeygen" />

### func (Ed25519) InitKeygen

```
func (ed25519 Ed25519) InitKeygen() (KeygenID, KeygenPrivateKey, error)
```

All parties must call this function **before** calling Keygen. All parties receive a ([KeygenID](#type-keygenid), [KeygenPrivateKey](#type-keygenprivatekey)) as an output from this function. The [KeygenID](#type-keygenid) must be sent through an authenticated communication channel to all other devices we wish to perform [Ed25519.Keygen](#func-ed25519-keygen) with. Once we have the [KeygenID](#type-keygenid)-s of all parties, then [Ed25519.Keygen](#func-ed25519-keygen) can be called with the **same** [KeygenPrivateKey](#type-keygenprivatekey) as was returned here.

<a name="Ed25519.Keygen" />

### func (Ed25519) Keygen

```
func (ed25519 Ed25519) Keygen(roomUuid RoomUUID, numParties uint16, threshold uint16, keygenPrivateKey KeygenPrivateKey, keygenIDs []KeygenID) (Ed25519SecretShare, Ed25519PublicKey, error)
```

Generate a keypair for the given number of parties and threshold.

:::warning[Notice]
`keygenPrivateKey` should be discarded after the successful completion of calling this function.
:::

Requires configuring the `threshold` and total number of participants (`numParties`) who will hold a secret share. This party's [KeygenPrivateKey](#type-keygenprivatekey) must be provided as well as an array of [KeygenID](#type-keygenid)-s (created using [Ed25519.InitKeygen](#func-ed25519-initkeygen)) received from all other parties we wish to share the keypair with.

Returns an [Ed25519PublicKey](#type-ed25519publickey) and an [Ed25519SecretShare](#type-ed25519secretshare) that contains the public key as well as the **secret** data that can be used for signing.

###### Example

```

// Your server side creates a room for 3 parties using its API_KEY
// Creating a room uuid should always happen on the server side using your API_KEY
const N = 3
const T = 2
const API_KEY = "MY_API_KEY"

ed25519 := NewEd25519("")
keygenRoomUuid, err := ed25519.CreateRoom(N, API_KEY)
if err != nil {
	panic(err)
}
// All parties call initKeygen to get a KeygenID and a KeygenPrivateKey
keygenID, keygenPrivKey, err := ed25519.InitKeygen()
if err != nil {
	panic(err)
}
// Send the keygenID to all other parties
_ = keygenID
// All parties receive the keygenIds from all other parties
keygenIds := []KeygenID{"keygenID1", "keygenID2"}
// All parties join the keygen room
secretShare, pk, err := ed25519.Keygen(keygenRoomUuid, N, T, keygenPrivKey, keygenIds)
if err != nil {
	panic(err)
}
// The public key can now be used to verify signatures
_, _ = secretShare, pk

```

<a name="Ed25519.OfflineExportFullPrivateKey" />

### func (Ed25519) OfflineExportFullPrivateKey

```
func (ed25519 Ed25519) OfflineExportFullPrivateKey(shares []Ed25519SecretShare) (string, error)
```

Receives as input an array of `threshold` [Ed25519SecretShare](#type-ed25519secretshare)-s and locally computes the full private key (`spriv`). The main use case for this function is in an offline recovery setting where [Ed25519SecretShare](#type-ed25519secretshare)-s are collected manually and used to recover the full private key on an air-gapped server/device.

Returns a string containing the full `spriv`.

<a name="Ed25519.Refresh" />

### func (Ed25519) Refresh

```
func (ed25519 Ed25519) Refresh(roomUuid RoomUUID, share Ed25519SecretShare) (Ed25519SecretShare, Ed25519PublicKey, error)
```

Used for refreshing the **secret** material of all parties without altering the public key at all. Takes an [Ed25519SecretShare](#type-ed25519secretshare) as input and returns a new one for the same public key but with fresh key material. Be careful to delete the [Ed25519SecretShare](#type-ed25519secretshare) given as input before it is certain that all devices have properly stored the fresh [Ed25519SecretShare](#type-ed25519secretshare) that is output. Note that the new [Ed25519SecretShare](#type-ed25519secretshare)-s may only be used with each other, attempting to use older [Ed25519SecretShare](#type-ed25519secretshare)-s with newer ones for signing will result in failure.

The motivation for using refresh is to enhance security by switching the secret key material frequently, this means that an adversary will need to compromise multiple devices **at the same time** in order to compromise the private key.

###### Example

```

const N = 3
const API_KEY = "MY_API_KEY"
// An Ed25519SecretShare is generated using Keygen
// secretShare, pk, err := ed25519.Keygen(...)
var secretShare Ed25519SecretShare
// Some time passes ...
// We now refresh the secret key material of our public key
ed25519 := NewEd25519("")
refreshRoomUuid, err := ed25519.CreateRoom(N, API_KEY)
if err != nil {
	panic(err)
}

// Note: the public key returned here is the same as the one returned by the keygen
refreshedShare, _, err := ed25519.Refresh(refreshRoomUuid, secretShare)
if err != nil {
	panic(err)
}
// refreshedShare can now be used for signing under the same T threshold, as well as be refreshed again
_ = refreshedShare

```

<a name="Ed25519.ReshareNewParty" />

### func (Ed25519) ReshareNewParty

```
func (ed25519 Ed25519) ReshareNewParty(roomUuid RoomUUID, newThreshold uint16, keygenPrivateKey KeygenPrivateKey, keygenIDs []KeygenID) (Ed25519SecretShare, Ed25519PublicKey, error)
```

WARNING: Key resharing is an **advanced** feature of the SDK. We strongly advise consulting with the Sodot team **before** using it, as incorrect usage might lead to the **detriment** of the private key **security**. To use the feature correctly, developers using this feature must make sure that at least `n - t + 1` parties of the `t-of-n` signing quorum delete their current shares before using the resharing of the private key. Also, after resharing, the resharing operation must not be considered complete until such deletion has occurred. Since deleting a share **cannot** be guaranteed cryptographically, it **must** be guaranteed by the software architecture (hence, by the developers using the SDK).

Resharing the **private key** of the `t-of-n` quorum of signers, the resultant key shares will be of the exact **same** public key as the previous quorum. Resharing should be used in cases where we aim to modify the current `t-of-n` quorum with a new quorum with `newT-of-newN` signers for the same public key.

This is the method that a new party (meaning one that does not currently have an [Ed25519SecretShare](#type-ed25519secretshare) ) should use for receiving a key share in the new `newT-of-newN` quorum. The method takes the same input parameters as [Ed25519.Keygen](#func-ed25519-keygen) since for a new party joining the quorum the `Reshare` operation is very similar to a `Keygen` operation. In order to receive the [KeygenID](#type-keygenid)-s of parties that are already a part of the quorum, those parties will need to call \[ExportID] and send the result to the parties in the new quorum.

Returns an [Ed25519SecretShare](#type-ed25519secretshare) with the **secret** data that can be used for signing as well as the [Ed25519PublicKey](#type-ed25519publickey).

###### Example

```

const N = 5
const newT = 5
const API_KEY = "MY_API_KEY"
// A signing quorum of `3-of-5` is set up without this party.
// Some time passes...
// Now this party wishes to be part of a new quorum of `5-of-6`.
//
// The app server creates a room for newN(= 6) parties.
ed25519 := NewEd25519("")
reshareRoomUuid, err := ed25519.CreateRoom(N, API_KEY)
if err != nil {
	panic(err)
}

// At least T(= 3) parties now join the reshare room using the current secret key material (this will be done using `ReshareRemainingParty`), all new parties will then join the reshare room using their `KeygenPrivateKey` using `ReshareNewParty`.
keygenID, keygenPrivKey, err := ed25519.InitKeygen()
if err != nil {
	panic(err)
}
// This new party will send its `KeygenID` to all other parties.
// This party will also receive the `KeygenID`s of all other parties of the new quorum.
keygenIds := []KeygenID{"keygenID1", keygenID, "keygenID3", "keygenID4", "keygenID5", "keygenID6"} // Note that here we must include our own `KeygenID` as well, the order of the ids doesn't matter.

// Note: the public key returned here is the same as the one returned by the keygen
newShare, _, err := ed25519.ReshareNewParty(reshareRoomUuid, newT, keygenPrivKey, keygenIds)
if err != nil {
	panic(err)
}
// newShare can now be used for signing under the newT(= 5) threshold with the same public key, as well as be reshared again
_ = newShare

```

<a name="Ed25519.ReshareRemainingParty" />

### func (Ed25519) ReshareRemainingParty

```
func (ed25519 Ed25519) ReshareRemainingParty(roomUuid RoomUUID, newThreshold uint16, share Ed25519SecretShare, keygenIDs []KeygenID) (Ed25519SecretShare, Ed25519PublicKey, error)
```

WARNING: Key resharing is an **advanced** feature of the SDK. We strongly advise consulting with the Sodot team **before** using it, as incorrect usage might lead to the **detriment** of the private key **security**. To use the feature correctly, developers using this feature must make sure that at least `n - t + 1` parties of the `t-of-n` signing quorum delete their current shares before using the resharing of the private key. Also, after resharing, the resharing operation must not be considered complete until such deletion has occurred. Since deleting a share **cannot** be guaranteed cryptographically, it **must** be guaranteed by the software architecture (hence, by the developers using the SDK).

Resharing the **private key** of the `t-of-n` quorum of signers, the resultant key shares will be of the exact **same** public key as the previous quorum. Resharing should be used in cases where we aim to modify the current `t-of-n` quorum with a new quorum with `newT-of-newN` signers for the same public key.

This is the method that a remaining party (meaning one that does currently have a key share) should use for receiving a new key share in the new `newT-of-newN` quorum. The method takes the same input parameters as [Ed25519.ReshareNewParty](#func-ed25519-resharenewparty) except that it will use its existing [Ed25519SecretShare](#type-ed25519secretshare) instead of a new [KeygenPrivateKey](#type-keygenprivatekey). In order to receive the [KeygenID](#type-keygenid)-s of parties that are already a part of the quorum, those parties will need to call \[ExportID] and send the result to the parties in the new quorum.

Returns a new [Ed25519SecretShare](#type-ed25519secretshare) with the **secret** data that can be used for signing as well as the [Ed25519PublicKey](#type-ed25519publickey).

###### Example

```

const N = 5
const newT = 5
const API_KEY = "MY_API_KEY"
// A signing quorum of `3-of-5` is set up with this party.
// secretShare, pk, err := ed25519.Keygen(...)
var secretShare Ed25519SecretShare
//
// Some time passes...
// Now this party wishes to be part of a new quorum of `5-of-6`.
//
// The app server creates a room for newN(= 6) parties.
ed25519 := NewEd25519("")
reshareRoomUuid, err := ed25519.CreateRoom(N, API_KEY)
if err != nil {
	panic(err)
}

// At least T(= 3) parties now join the reshare room using the current secret key material (this will be done using `ReshareRemainingParty`), all new parties will then join the reshare room using their `KeygenPrivateKey` using `ReshareNewParty`.
keygenID, err := ed25519.ExportID(secretShare) // This is a remaining party
if err != nil {
	panic(err)
}

// This remaining party will send its `KeygenID` to all other parties (new - via an authenticated channel and remaining - via any channel).
// This party will also receive the `KeygenID`s of all other parties of the new quorum (new - via an authenticated channel and remaining - via any channel).
keygenIds := []KeygenID{"keygenID1", "keygenID2", keygenID, "keygenID4", "keygenID5", "keygenID6"} // Note that here we must include our own `KeygenID` as well, the order of the ids doesn't matter.

// Note: the public key returned here is the same as the one returned by the keygen
newShare, _, err := ed25519.ReshareRemainingParty(reshareRoomUuid, newT, secretShare, keygenIds)
if err != nil {
	panic(err)
}
// newShare can now be used for signing under the newT(= 5) threshold with the same public key, as well as be reshared again
_ = newShare

```

<a name="Ed25519.Sign" />

### func (Ed25519) Sign

```
func (ed25519 Ed25519) Sign(roomUuid RoomUUID, share Ed25519SecretShare, msg []byte, derivationPath []uint32) (Ed25519Signature, error)
```

Sign a message with an [Ed25519SecretShare](#type-ed25519secretshare) created using [Ed25519.Keygen](#func-ed25519-keygen). `derivationPath` must be a BIP-32 non-hardened derivation path to use for signing `msg`.

Returns the signature of the message.

###### Example

```

// To sign a message, create a signing room on the server side, using your API_KEY
const T = 2
const API_KEY = "MY_API_KEY"
// An Ed25519SecretShare is generated using Keygen
// secretShare, pk, err := ed25519.Keygen(...)
var secretShare Ed25519SecretShare
ed25519 := NewEd25519("")
signingRoomUuid, err := ed25519.CreateRoom(T, API_KEY)
if err != nil {
	panic(err)
}

// Pick the derivation path of the public key you want to sign for
derivationPath := []uint32{44, 60, 0, 0, 0}
// Get the public key for the derivation path
derivedPubKey, err := ed25519.DerivePubkey(secretShare, derivationPath)
if err != nil {
	panic(err)
}
// The derived public key can now be used to verify signatures with the same derivation path
_ = derivedPubKey

// Define the message
message := []byte("my message")
// 2 parties join the signing room
signature, err := ed25519.Sign(signingRoomUuid, secretShare, message, derivationPath)
if err != nil {
	panic(err)
}
// This signature can now be verified against pubkey
_ = signature

```

<a name="Ed25519PublicKey" />

## type Ed25519PublicKey

An Ed25519 public key, generated by the [Ed25519.Keygen](#func-ed25519-keygen) function.

```
type Ed25519PublicKey [32]byte
```

<a name="Ed25519PublicKeyFromString" />

### func Ed25519PublicKeyFromString

```
func Ed25519PublicKeyFromString(s string) (Ed25519PublicKey, error)
```

Ed25519PublicKeyFromString parses a hex string into an Ed25519PublicKey.

<a name="Ed25519PublicKey.String" />

### func (\*Ed25519PublicKey) String

```
func (pubkey *Ed25519PublicKey) String() string
```

String returns the hex representation of the public key.

<a name="Ed25519SecretShare" />

## type Ed25519SecretShare

The per-party **private** key material that is used for threshold signing

```
type Ed25519SecretShare string
```

<a name="Ed25519SecretShare.Bytes" />

### func (Ed25519SecretShare) Bytes

```
func (share Ed25519SecretShare) Bytes() []byte
```

Bytes returns the raw representation of the Ed25519SecretShare.

<a name="Ed25519Signature" />

## type Ed25519Signature

An Ed25519 signature, generated by the [Ed25519.Sign](#func-ed25519-sign) function.

```
type Ed25519Signature [64]byte
```

<a name="Ed25519Signature.String" />

### func (\*Ed25519Signature) String

```
func (sig *Ed25519Signature) String() string
```

String returns the hex representation of the signature.

<a name="ExportableEd25519" />

## type ExportableEd25519

Class providing the functionality for the ExportableEd25519 protocol via the FROST MPC protocol.

```
type ExportableEd25519 struct {
    HostUrl string
}
```

<a name="NewExportableEd25519" />

### func NewExportableEd25519

```
func NewExportableEd25519(hostUrl string) ExportableEd25519
```

NewExportableEd25519 creates a new ExportableEd25519 instance

host URL to use, if "" is passed, the default host url(`SODOT_RELAY_URL`) will be used

<a name="ExportableEd25519.CreateRoom" />

### func (ExportableEd25519) CreateRoom

```
func (exportableEd25519 ExportableEd25519) CreateRoom(numParties uint16, apiKey string) (RoomUUID, error)
```

Creates a room for the given number of parties. A room is a one time instance used to perform a single MPC operation(keygen/signing/refresh etc.) between parties.

This function should be called in the backend so to not embed the API key in code that is distributed to the users. After the backend calls this function, the other parties can join the room by calling the relevant keygen/signing/refresh/etc. operation.

Returns a [RoomUUID](#type-roomuuid) of the created room.

<a name="ExportableEd25519.ExportFullPrivateKey" />

### func (ExportableEd25519) ExportFullPrivateKey

```
func (exportableEd25519 ExportableEd25519) ExportFullPrivateKey(roomUuid RoomUUID, share ExportableEd25519SecretShare, toExportID KeygenID) (string, error)
```

Combine all [ExportableEd25519SecretShare](#type-exportableed25519secretshare)-s and export the full private key to a single party. Requires a threshold amount of parties to participate. `toExportID` specifies the [KeygenID](#type-keygenid) of the party that should receive the private key, all parties must provide the same [KeygenID](#type-keygenid) or else export will fail.

The party being exported to will receive a `string` containing the full `spriv`, while the rest will receive an empty string.

<a name="ExportableEd25519.ExportID" />

### func (ExportableEd25519) ExportID

```
func (exportableEd25519 ExportableEd25519) ExportID(share ExportableEd25519SecretShare) (KeygenID, error)
```

Extracts the [KeygenID](#type-keygenid) from an [ExportableEd25519SecretShare](#type-exportableed25519secretshare). Useful for reshare operations.

<a name="ExportableEd25519.GetPubkey" />

### func (ExportableEd25519) GetPubkey

```
func (exportableEd25519 ExportableEd25519) GetPubkey(share ExportableEd25519SecretShare) (Ed25519PublicKey, error)
```

Get the public key for an [ExportableEd25519SecretShare](#type-exportableed25519secretshare).

<a name="ExportableEd25519.ImportPrivateKeyImporter" />

### func (ExportableEd25519) ImportPrivateKeyImporter

```
func (exportableEd25519 ExportableEd25519) ImportPrivateKeyImporter(roomUuid RoomUUID, threshold uint16, privateKey PrivateKey, keygenPrivateKey KeygenPrivateKey, keygenIDs []KeygenID) (ExportableEd25519SecretShare, Ed25519PublicKey, error)
```

WARNING: Private key import is an **advanced** feature of the SDK. We strongly advise consulting with the Sodot team **before** using it, due to a full private key being imported from a different system. Secret shares generated from imported private keys will always have the risk of the private key having been compromised in the past or in the future in case the private key is not deleted after the import operation.

Importing a **full private key**, and sharing into a `T-of-N` sharing, the resultant key shares will be of the exact **same** public key as the full private key.

This is the method that an importing party (meaning one the party in possesion of the private key) should use for receiving a key share in the new `T-of-N` quorum.

Returns an [ExportableEd25519SecretShare](#type-exportableed25519secretshare) with the **secret** data that can be used for signing as well as the [Ed25519PublicKey](#type-ed25519publickey).

<a name="ExportableEd25519.ImportPrivateKeyRecipient" />

### func (ExportableEd25519) ImportPrivateKeyRecipient

```
func (exportableEd25519 ExportableEd25519) ImportPrivateKeyRecipient(roomUuid RoomUUID, threshold uint16, keygenPrivateKey KeygenPrivateKey, keygenIDs []KeygenID) (ExportableEd25519SecretShare, Ed25519PublicKey, error)
```

WARNING: Private key import is an **advanced** feature of the SDK. We strongly advise consulting with the Sodot team **before** using it, due to a full private key being imported from a different system. Secret shares generated from imported private keys will always have the risk of the private key having been compromised in the past or in the future in case the private key is not deleted after the import operation.

Importing a **full private key**, and sharing into a `T-of-N` sharing, the resultant key shares will be of the exact **same** public key as the full private key.

This is the method that a new party (meaning one that does not currently have the private key) should use for receiving a key share in the new `T-of-N` quorum. The method takes the same input parameters as [ExportableEd25519.SampleKey](#func-exportableed25519-samplekey) since for a new party joining the quorum the `Import` operation is very similar to a `SampleKey` operation.

Returns an [ExportableEd25519SecretShare](#type-exportableed25519secretshare) with the **secret** data that can be used for signing as well as the [Ed25519PublicKey](#type-ed25519publickey).

<a name="ExportableEd25519.InitKeygen" />

### func (ExportableEd25519) InitKeygen

```
func (exportableEd25519 ExportableEd25519) InitKeygen() (KeygenID, KeygenPrivateKey, error)
```

All parties must call this function **before** calling SampleKey or ReceiveKey. All parties receive a ([KeygenID](#type-keygenid), [KeygenPrivateKey](#type-keygenprivatekey)) as an output from this function. The [KeygenID](#type-keygenid) must be sent through an authenticated communication channel to all other devices we wish to perform key generation with. Once we have the [KeygenID](#type-keygenid)-s of all parties, then SampleKey or ReceiveKey can be called with the **same** [KeygenPrivateKey](#type-keygenprivatekey) as was returned here.

<a name="ExportableEd25519.OfflineExportFullPrivateKey" />

### func (ExportableEd25519) OfflineExportFullPrivateKey

```
func (exportableEd25519 ExportableEd25519) OfflineExportFullPrivateKey(shares []ExportableEd25519SecretShare) (string, error)
```

Receives as input an array of `threshold` [ExportableEd25519SecretShare](#type-exportableed25519secretshare)-s and locally computes the full private key. The main use case for this function is in an offline recovery setting where [ExportableEd25519SecretShare](#type-exportableed25519secretshare)-s are collected manually and used to recover the full private key on an air-gapped server/device.

Returns a string containing the full private key in hexadecimal format.

<a name="ExportableEd25519.ReceiveKey" />

### func (ExportableEd25519) ReceiveKey

```
func (exportableEd25519 ExportableEd25519) ReceiveKey(roomUuid RoomUUID, numParties uint16, threshold uint16, keygenPrivateKey KeygenPrivateKey, keygenIDs []KeygenID) (ExportableEd25519SecretShare, Ed25519PublicKey, error)
```

Receive a keypair for the given number of parties and threshold.

:::warning[Notice]
`keygenPrivateKey` should be discarded after the successful completion of calling this function.
:::

Requires configuring the `threshold` and total number of participants (`numParties`) who will hold a secret share. This party's [KeygenPrivateKey](#type-keygenprivatekey) must be provided as well as an array of [KeygenID](#type-keygenid)-s (created using [ExportableEd25519.InitKeygen](#func-exportableed25519-initkeygen)) received from all other parties we wish to share the keypair with.

Returns an [Ed25519PublicKey](#type-ed25519publickey) and an [ExportableEd25519SecretShare](#type-exportableed25519secretshare) that contains the public key as well as the **secret** data that can be used for signing.

<a name="ExportableEd25519.Refresh" />

### func (ExportableEd25519) Refresh

```
func (exportableEd25519 ExportableEd25519) Refresh(roomUuid RoomUUID, share ExportableEd25519SecretShare) (ExportableEd25519SecretShare, Ed25519PublicKey, error)
```

Used for refreshing the **secret** material of all parties without altering the public key at all. Takes an [ExportableEd25519SecretShare](#type-exportableed25519secretshare) as input and returns a new one for the same public key but with fresh key material. Be careful to delete the [ExportableEd25519SecretShare](#type-exportableed25519secretshare) given as input before it is certain that all devices have properly stored the fresh [ExportableEd25519SecretShare](#type-exportableed25519secretshare) that is output. Note that the new [ExportableEd25519SecretShare](#type-exportableed25519secretshare)-s may only be used with each other, attempting to use older [ExportableEd25519SecretShare](#type-exportableed25519secretshare)-s with newer ones for signing will result in failure.

The motivation for using refresh is to enhance security by switching the secret key material frequently, this means that an adversary will need to compromise multiple devices **at the same time** in order to compromise the private key.

<a name="ExportableEd25519.ReshareNewParty" />

### func (ExportableEd25519) ReshareNewParty

```
func (exportableEd25519 ExportableEd25519) ReshareNewParty(roomUuid RoomUUID, newThreshold uint16, keygenPrivateKey KeygenPrivateKey, keygenIDs []KeygenID) (ExportableEd25519SecretShare, Ed25519PublicKey, error)
```

WARNING: Key resharing is an **advanced** feature of the SDK. We strongly advise consulting with the Sodot team **before** using it, as incorrect usage might lead to the **detriment** of the private key **security**. To use the feature correctly, developers using this feature must make sure that at least `n - t + 1` parties of the `t-of-n` signing quorum delete their current shares before using the resharing of the private key. Also, after resharing, the resharing operation must not be considered complete until such deletion has occurred. Since deleting a share **cannot** be guaranteed cryptographically, it **must** be guaranteed by the software architecture (hence, by the developers using the SDK).

Resharing the **private key** of the `t-of-n` quorum of signers, the resultant key shares will be of the exact **same** public key as the previous quorum. Resharing should be used in cases where we aim to modify the current `t-of-n` quorum with a new quorum with `newT-of-newN` signers for the same public key.

This is the method that a new party (meaning one that does not currently have an [ExportableEd25519SecretShare](#type-exportableed25519secretshare) ) should use for receiving a key share in the new `newT-of-newN` quorum. The method takes the same input parameters as [ExportableEd25519.SampleKey](#func-exportableed25519-samplekey) since for a new party joining the quorum the `Reshare` operation is very similar to a `SampleKey` operation. In order to receive the [KeygenID](#type-keygenid)-s of parties that are already a part of the quorum, those parties will need to call \[ExportID] and send the result to the parties in the new quorum.

Returns an [ExportableEd25519SecretShare](#type-exportableed25519secretshare) with the **secret** data that can be used for signing as well as the [Ed25519PublicKey](#type-ed25519publickey).

<a name="ExportableEd25519.ReshareRemainingParty" />

### func (ExportableEd25519) ReshareRemainingParty

```
func (exportableEd25519 ExportableEd25519) ReshareRemainingParty(roomUuid RoomUUID, newThreshold uint16, share ExportableEd25519SecretShare, keygenIDs []KeygenID) (ExportableEd25519SecretShare, Ed25519PublicKey, error)
```

WARNING: Key resharing is an **advanced** feature of the SDK. We strongly advise consulting with the Sodot team **before** using it, as incorrect usage might lead to the **detriment** of the private key **security**. To use the feature correctly, developers using this feature must make sure that at least `n - t + 1` parties of the `t-of-n` signing quorum delete their current shares before using the resharing of the private key. Also, after resharing, the resharing operation must not be considered complete until such deletion has occurred. Since deleting a share **cannot** be guaranteed cryptographically, it **must** be guaranteed by the software architecture (hence, by the developers using the SDK).

Resharing the **private key** of the `t-of-n` quorum of signers, the resultant key shares will be of the exact **same** public key as the previous quorum. Resharing should be used in cases where we aim to modify the current `t-of-n` quorum with a new quorum with `newT-of-newN` signers for the same public key.

This is the method that a remaining party (meaning one that does currently have a key share) should use for receiving a new key share in the new `newT-of-newN` quorum. The method takes the same input parameters as [ExportableEd25519.ReshareNewParty](#func-exportableed25519-resharenewparty) except that it will use its existing [ExportableEd25519SecretShare](#type-exportableed25519secretshare) instead of a new [KeygenPrivateKey](#type-keygenprivatekey). In order to receive the [KeygenID](#type-keygenid)-s of parties that are already a part of the quorum, those parties will need to call \[ExportID] and send the result to the parties in the new quorum.

Returns a new [ExportableEd25519SecretShare](#type-exportableed25519secretshare) with the **secret** data that can be used for signing as well as the [Ed25519PublicKey](#type-ed25519publickey).

<a name="ExportableEd25519.SampleKey" />

### func (ExportableEd25519) SampleKey

```
func (exportableEd25519 ExportableEd25519) SampleKey(roomUuid RoomUUID, numParties uint16, threshold uint16, keygenPrivateKey KeygenPrivateKey, keygenIDs []KeygenID) (ExportableEd25519SecretShare, Ed25519PublicKey, error)
```

Generate a keypair for the given number of parties and threshold.

:::warning[Notice]
`keygenPrivateKey` should be discarded after the successful completion of calling this function.
:::

Requires configuring the `threshold` and total number of participants (`numParties`) who will hold a secret share. This party's [KeygenPrivateKey](#type-keygenprivatekey) must be provided as well as an array of [KeygenID](#type-keygenid)-s (created using [ExportableEd25519.InitKeygen](#func-exportableed25519-initkeygen)) received from all other parties we wish to share the keypair with.

Returns an [Ed25519PublicKey](#type-ed25519publickey) and an [ExportableEd25519SecretShare](#type-exportableed25519secretshare) that contains the public key as well as the **secret** data that can be used for signing.

<a name="ExportableEd25519.Sign" />

### func (ExportableEd25519) Sign

```
func (exportableEd25519 ExportableEd25519) Sign(roomUuid RoomUUID, share ExportableEd25519SecretShare, msg []byte) (Ed25519Signature, error)
```

Sign a message with an [ExportableEd25519SecretShare](#type-exportableed25519secretshare) created using SampleKey or ReceiveKey.

Returns the signature of the message.

<a name="ExportableEd25519SecretShare" />

## type ExportableEd25519SecretShare

The per-party **private** key material that is used for threshold signing

```
type ExportableEd25519SecretShare string
```

<a name="ExportableEd25519SecretShare.Bytes" />

### func (ExportableEd25519SecretShare) Bytes

```
func (share ExportableEd25519SecretShare) Bytes() []byte
```

Bytes returns the raw representation of the ExportableEd25519SecretShare.

<a name="KeygenID" />

## type KeygenID

KeygenID is a base58 string representing the ID of the party in the key generation protocol.

```
type KeygenID string
```

<a name="KeygenPrivateKey" />

## type KeygenPrivateKey

KeygenPrivateKey is a hex string representing the private key of the corresponding KeygenID.

```
type KeygenPrivateKey string
```

<a name="KeygenPrivateKey.Bytes" />

### func (KeygenPrivateKey) Bytes

```
func (privkey KeygenPrivateKey) Bytes() []byte
```

Bytes returns the raw representation of the KeygenPrivateKey.

<a name="MessageHash" />

## type MessageHash

A 32 byte message hash used for signing ECDSA messages.

```
// A SHA256 hash of the string 'Hello World'
messageHash := MessageHashFromSha256([]byte('Hello World'))
// A Keccak256 hash of the string 'Hello World'
messageHash := MessageHashFromKeccak256([]byte('Hello World'))
// In case you already have a hashed value you can just call the constructor with it
messageHash := MessageHash{71, 111, 38, ... , 23}

```

```
type MessageHash [32]byte
```

<a name="MessageHashFromKeccak256" />

### func MessageHashFromKeccak256

```
func MessageHashFromKeccak256(data []byte) MessageHash
```

Creates a [MessageHash](#type-messagehash) by hashing `data` with Keccak256

<a name="MessageHashFromSha256" />

### func MessageHashFromSha256

```
func MessageHashFromSha256(data []byte) MessageHash
```

Creates a [MessageHash](#type-messagehash) by hashing `data` with SHA256

<a name="MessageHashFromSha256d" />

### func MessageHashFromSha256d

```
func MessageHashFromSha256d(data []byte) MessageHash
```

Creates a [MessageHash](#type-messagehash) by hashing `data` with Double SHA256 (Bitcoin's Sha256d)

<a name="PrivateKey" />

## type PrivateKey

PrivateKey is a 64 characters hex string representing some private key.

```
type PrivateKey string
```

<a name="PrivateKey.Bytes" />

### func (PrivateKey) Bytes

```
func (privkey PrivateKey) Bytes() []byte
```

Bytes returns the raw representation of the PrivateKey.

<a name="RoomUUID" />

## type RoomUUID

RoomUUID is a hex string representing a room, which is created for each MPC operation (e.g. Signing, Keygen, Refresh, etc.) and acts as a session identifier to synchronize all involved parties.

```
type RoomUUID string
```

<a name="RoomUUID.Bytes" />

### func (RoomUUID) Bytes

```
func (uuid RoomUUID) Bytes() []byte
```

Bytes returns the raw representation of the RoomUUID.

<a name="Sr25519" />

## type Sr25519

Sr25519 provides functionality for the Sr25519 protocol, implementing the FROST MPC protocol. This class enables operations such as key generation, signing, and refreshing secret shares in a threshold setting.

```
type Sr25519 struct {
    HostUrl string
}
```

###### Example

```

const N = 3
const T = 2
const API_KEY = "MY_API_KEY"

sr25519 := NewSr25519("")
keygenRoomUuid, err := sr25519.CreateRoom(N, API_KEY)
if err != nil {
	panic(err)
}
// All parties call initKeygen to get a KeygenID and a KeygenPrivateKey
keygenID, keygenPrivKey, err := sr25519.InitKeygen()
if err != nil {
	panic(err)
}
// Send the keygenID to all other parties
_ = keygenID
// All parties receive the keygenIds from all other parties
keygenIds := []KeygenID{"keygenID1", "keygenID2"}
// All parties join the keygen room
secretShare, pk, err := sr25519.Keygen(keygenRoomUuid, N, T, keygenPrivKey, keygenIds)
if err != nil {
	panic(err)
}
// The public key can now be used to verify signatures
_ = pk

// Pick the derivation path of the public key you want to sign for
derivationPath := []string{"this", "is", "a", "derivation", "path"}
// Get the public key for the derivation path
derivedPubKey, err := sr25519.DerivePubkey(secretShare, derivationPath)
if err != nil {
	panic(err)
}
// The derived public key can now be used to verify signatures with the same derivation path
_ = derivedPubKey
// To sign a message, create a signing room on the server side, using your API_KEY
signingRoomUuid, err := sr25519.CreateRoom(T, API_KEY)
if err != nil {
	panic(err)
}
// Define the message
message := []byte("my message")
// 2 parties join the signing room
signature, err := sr25519.Sign(signingRoomUuid, secretShare, message, derivationPath)
if err != nil {
	panic(err)
}
// This signature can now be verified against pubkey
_ = signature
// Refreshing the secret key material
// Your server creates a room for 3 parties
refreshRoomUuid, err := sr25519.CreateRoom(N, API_KEY)
if err != nil {
	panic(err)
}
// All parties join the refresh room
// Note: the public key returned here is the same as the one returned by the keygen
refreshedShare, _, err := sr25519.Refresh(refreshRoomUuid, secretShare)
if err != nil {
	panic(err)
}

// Signing using the new secret key material
// The room is again created by the server
signingRoomUuid2, err := sr25519.CreateRoom(T, API_KEY)
if err != nil {
	panic(err)
}

message2 := []byte("my new message")
signature2, err := sr25519.Sign(signingRoomUuid2, refreshedShare, message2, derivationPath)
if err != nil {
	panic(err)
}
// This signature can now be verified against pubkey
_ = signature2

```

<a name="NewSr25519" />

### func NewSr25519

```
func NewSr25519(hostUrl string) Sr25519
```

NewSr25519 creates a new Sr25519 instance with a specific host relay address. If an empty string is passed as the host URL, the default host URL (`SODOT_RELAY_URL`) will be used.

<a name="Sr25519.CreateRoom" />

### func (Sr25519) CreateRoom

```
func (sr25519 Sr25519) CreateRoom(numParties uint16, apiKey string) (RoomUUID, error)
```

Creates a room for the given number of parties. A room is a one time instance used to perform a single MPC operation(keygen/signing/refresh etc.) between parties.

This function should be called in the backend so to not embed the API key in code that is distributed to the users. After the backend calls this function, the other parties can join the room by calling the relevant keygen/signing/refresh/etc. operation.

Returns a [RoomUUID](#type-roomuuid) of the created room.

<a name="Sr25519.DerivePrivateKeyFromPrivateKey" />

### func (Sr25519) DerivePrivateKeyFromPrivateKey

```
func (sr25519 Sr25519) DerivePrivateKeyFromPrivateKey(privateKey PrivateKey, isPrivateKeyRaw bool, derivationPath []string) (PrivateKey, error)
```

DerivePrivateKeyFromPrivateKey derives a private key from another private key using a derivation path.

You need to specify `isPrivateKeyRaw` in order to say if it's a raw (scalar) private key, or the pre-image of the `MiniSecret` for sr25519 keys.

<a name="Sr25519.DerivePubkey" />

### func (Sr25519) DerivePubkey

```
func (sr25519 Sr25519) DerivePubkey(share Sr25519SecretShare, derivationPath []string) (Sr25519PublicKey, error)
```

DerivePubkey derives a public key from an Sr25519SecretShare using a soft sr25519 derivation path.

<a name="Sr25519.DerivePubkeyFromPubKey" />

### func (Sr25519) DerivePubkeyFromPubKey

```
func (sr25519 Sr25519) DerivePubkeyFromPubKey(pubkey Sr25519PublicKey, derivationPath []string) (Sr25519PublicKey, error)
```

DerivePubkeyFromPubKey derives a public key from another public key using soft sr25519 derivation path. the public key can be obtained from the [Sr25519.GetPubKey](#func-sr25519-getpubkey) function.

<a name="Sr25519.ExportFullPrivateKey" />

### func (Sr25519) ExportFullPrivateKey

```
func (sr25519 Sr25519) ExportFullPrivateKey(roomUuid RoomUUID, share Sr25519SecretShare, toExportID KeygenID) (string, error)
```

ExportFullPrivateKey combines all Sr25519SecretShares and exports the full private key to a single party.

The party being exported to will receive the full private key, while the rest will receive an empty string.

<a name="Sr25519.ExportID" />

### func (Sr25519) ExportID

```
func (sr25519 Sr25519) ExportID(share Sr25519SecretShare) (KeygenID, error)
```

ExportID extracts the KeygenID from an Sr25519SecretShare.

This is useful for reshare operations.

<a name="Sr25519.GetPubKey" />

### func (Sr25519) GetPubKey

```
func (sr25519 Sr25519) GetPubKey(share Sr25519SecretShare) (Sr25519PublicKey, error)
```

GetPubKey returns the shared public key from the given Sr25519SecretShare. This public key is the same as the one generated during the key generation process. The public key can be used either via third party libraries or via [Sr25519.DerivePubkeyFromPubKey](#func-sr25519-derivepubkeyfrompubkey) to derive public keys

<a name="Sr25519.ImportPrivateKeyImporter" />

### func (Sr25519) ImportPrivateKeyImporter

```
func (sr25519 Sr25519) ImportPrivateKeyImporter(roomUuid RoomUUID, threshold uint16, privateKey PrivateKey, keygenPrivateKey KeygenPrivateKey, keygenIDs []KeygenID, isPrivateKeyRaw bool) (Sr25519SecretShare, Sr25519PublicKey, error)
```

WARNING: Private key import is an **advanced** feature of the SDK. We strongly advise consulting with the Sodot team **before** using it, due to a full private key being imported from a different system. Secret shares generated from imported private keys will always have the risk of the private key having been compromised in the past or in the future in case the private key is not deleted after the import operation.

Importing a **full private key**, and sharing into a `T-of-N` sharing, the resultant key shares will be of the exact **same** public key as the full private key.

This is the method that an importing party (meaning one the party in possesion of the private key) should use for receiving a key share in the new `T-of-N` quorum.

You need to specify `isPrivateKeyRaw` in order to say if it's a raw (scalar) private key, or the pre-image of the `MiniSecret` for sr25519 keys.

Returns an [Sr25519SecretShare](#type-sr25519secretshare) with the **secret** data that can be used for signing as well as the [Sr25519PublicKey](#type-sr25519publickey).

###### Example

```

const N = 3
const T = 2
const API_KEY = "MY_API_KEY"
// A private key is created in some external system.
privateKey := PrivateKey("ec9cd36eacd63b9b11653aef8cb43838e1c6fca936efb68228dbfc37d2d3c00d")
// Some time passes...
// Now this party wishes to be part of a new quorum of `2-of-3` sharing of the private key.
//
// The app server creates a room for N(= 3) parties.
sr25519 := NewSr25519("")
importRoomUuid, err := sr25519.CreateRoom(N, API_KEY)
if err != nil {
	panic(err)
}

// The other parties must join the import room using the `ImportPrivateKeyRecipient` method.
keygenID, keygenPrivKey, err := sr25519.InitKeygen()
if err != nil {
	panic(err)
}
// This importing party will send its `KeygenID` to all other parties.
// This party will also receive the `KeygenID`s of all other parties of the new quorum.
keygenIds := []KeygenID{"keygenID1", keygenID, "keygenID3"} // Note that here we must include our own `KeygenID` as well, the order of the ids doesn't matter.

// Note: the public key returned here is the same as the public key of the imported key
newShare, _, err := sr25519.ImportPrivateKeyImporter(importRoomUuid, T, privateKey, keygenPrivKey, keygenIds, false)
if err != nil {
	panic(err)
}
// newShare can now be used for signing under the T(= 2) threshold with the same public key
_ = newShare

```

<a name="Sr25519.ImportPrivateKeyRecipient" />

### func (Sr25519) ImportPrivateKeyRecipient

```
func (sr25519 Sr25519) ImportPrivateKeyRecipient(roomUuid RoomUUID, threshold uint16, keygenPrivateKey KeygenPrivateKey, keygenIDs []KeygenID) (Sr25519SecretShare, Sr25519PublicKey, error)
```

WARNING: Private key import is an **advanced** feature of the SDK. We strongly advise consulting with the Sodot team **before** using it, due to a full private key being imported from a different system. Secret shares generated from imported private keys will always have the risk of the private key having been compromised in the past or in the future in case the private key is not deleted after the import operation.

Importing a **full private key**, and sharing into a `T-of-N` sharing, the resultant key shares will be of the exact **same** public key as the full private key.

This is the method that a new party (meaning one that does not currently have the private key) should use for receiving a key share in the new `T-of-N` quorum. The method takes the same input parameters as [Sr25519.Keygen](#func-sr25519-keygen) since for a new party joining the quorum the `Import` operation is very similar to a `Keygen` operation.

Returns an [Sr25519SecretShare](#type-sr25519secretshare) with the **secret** data that can be used for signing as well as the [Sr25519PublicKey](#type-sr25519publickey).

###### Example

```

const N = 3
const T = 2
const API_KEY = "MY_API_KEY"
// A private key is created in some external system.
// Some time passes...
// Now this party wishes to be part of a new quorum of `2-of-3` sharing of the private key.
//
// The app server creates a room for N(= 3) parties.
sr25519 := NewSr25519("")
importRoomUuid, err := sr25519.CreateRoom(N, API_KEY)
if err != nil {
	panic(err)
}

// The party with the private key must join the import room using the `ImportPrivateKeyImporter` method.
keygenID, keygenPrivKey, err := sr25519.InitKeygen()
if err != nil {
	panic(err)
}
// This new party will send its `KeygenID` to all other parties.
// This party will also receive the `KeygenID`s of all other parties of the new quorum.
keygenIds := []KeygenID{"keygenID1", keygenID, "keygenID3"} // Note that here we must include our own `KeygenID` as well, the order of the ids doesn't matter.

// Note: the public key returned here is the same as the public key of the imported key
newShare, _, err := sr25519.ImportPrivateKeyRecipient(importRoomUuid, T, keygenPrivKey, keygenIds)
if err != nil {
	panic(err)
}
// newShare can now be used for signing under the T(= 2) threshold with the same public key
_ = newShare

```

<a name="Sr25519.InitKeygen" />

### func (Sr25519) InitKeygen

```
func (sr25519 Sr25519) InitKeygen() (KeygenID, KeygenPrivateKey, error)
```

InitKeygen initializes the key generation process.

All parties must call this function before calling Keygen. Each party receives a KeygenID and KeygenPrivateKey. The KeygenID must be sent through an authenticated communication channel to all other devices participating in the key generation.

<a name="Sr25519.Keygen" />

### func (Sr25519) Keygen

```
func (sr25519 Sr25519) Keygen(roomUuid RoomUUID, numParties uint16, threshold uint16, keygenPrivateKey KeygenPrivateKey, keygenIDs []KeygenID) (Sr25519SecretShare, Sr25519PublicKey, error)
```

Keygen generates a keypair for the given number of parties and threshold.

:::warning[Notice]
`keygenPrivateKey` should be discarded after the successful completion of calling this function.
:::

Requires configuring the `threshold` and total number of participants (`numParties`) who will hold a secret share. This party's [KeygenPrivateKey](#type-keygenprivatekey) must be provided as well as an array of [KeygenID](#type-keygenid)-s (created using [Sr25519.InitKeygen](#func-sr25519-initkeygen)) received from all other parties we wish to share the keypair with.

Returns an [Sr25519PublicKey](#type-sr25519publickey) and an [Sr25519SecretShare](#type-sr25519secretshare) that contains the public key as well as the **secret** data that can be used for signing.

###### Example

```

// Your server side creates a room for 3 parties using its API_KEY
// Creating a room uuid should always happen on the server side using your API_KEY
const N = 3
const T = 2
const API_KEY = "MY_API_KEY"

sr25519 := NewSr25519("")
keygenRoomUuid, err := sr25519.CreateRoom(N, API_KEY)
if err != nil {
	panic(err)
}
// All parties call initKeygen to get a KeygenID and a KeygenPrivateKey
keygenID, keygenPrivKey, err := sr25519.InitKeygen()
if err != nil {
	panic(err)
}
// Send the keygenID to all other parties
_ = keygenID
// All parties receive the keygenIds from all other parties
keygenIds := []KeygenID{"keygenID1", "keygenID2"}
// All parties join the keygen room
secretShare, pk, err := sr25519.Keygen(keygenRoomUuid, N, T, keygenPrivKey, keygenIds)
if err != nil {
	panic(err)
}
// The public key can now be used to verify signatures
_, _ = secretShare, pk

```

<a name="Sr25519.OfflineExportFullPrivateKey" />

### func (Sr25519) OfflineExportFullPrivateKey

```
func (sr25519 Sr25519) OfflineExportFullPrivateKey(shares []Sr25519SecretShare) (string, error)
```

OfflineExportFullPrivateKey computes the full private key locally from an array of Sr25519SecretShares.

This function is intended for offline recovery scenarios where secret shares are collected manually.

<a name="Sr25519.Refresh" />

### func (Sr25519) Refresh

```
func (sr25519 Sr25519) Refresh(roomUuid RoomUUID, share Sr25519SecretShare) (Sr25519SecretShare, Sr25519PublicKey, error)
```

Refresh refreshes the secret material of all parties without altering the public key.

This function enhances security by switching the secret key material frequently. The new secret shares can only be used with each other. Be careful to delete the old Sr25519SecretShare after ensuring all devices have properly stored the new one.

###### Example

```

const N = 3
const API_KEY = "MY_API_KEY"
// An Sr25519SecretShare is generated using Keygen
// secretShare, pk, err := sr25519.Keygen(...)
var secretShare Sr25519SecretShare
// Some time passes ...
// We now refresh the secret key material of our public key
sr25519 := NewSr25519("")
refreshRoomUuid, err := sr25519.CreateRoom(N, API_KEY)
if err != nil {
	panic(err)
}

// Note: the public key returned here is the same as the one returned by the keygen
refreshedShare, _, err := sr25519.Refresh(refreshRoomUuid, secretShare)
if err != nil {
	panic(err)
}
// refreshedShare can now be used for signing under the same T threshold, as well as be refreshed again
_ = refreshedShare

```

<a name="Sr25519.ReshareNewParty" />

### func (Sr25519) ReshareNewParty

```
func (sr25519 Sr25519) ReshareNewParty(roomUuid RoomUUID, newThreshold uint16, keygenPrivateKey KeygenPrivateKey, keygenIDs []KeygenID) (Sr25519SecretShare, Sr25519PublicKey, error)
```

WARNING: Key resharing is an **advanced** feature of the SDK. We strongly advise consulting with the Sodot team **before** using it, as incorrect usage might lead to the **detriment** of the private key **security**. To use the feature correctly, developers using this feature must make sure that at least `n - t + 1` parties of the `t-of-n` signing quorum delete their current shares before using the resharing of the private key. Also, after resharing, the resharing operation must not be considered complete until such deletion has occurred. Since deleting a share **cannot** be guaranteed cryptographically, it **must** be guaranteed by the software architecture (hence, by the developers using the SDK).

Resharing the **private key** of the `t-of-n` quorum of signers, the resultant key shares will be of the exact **same** public key as the previous quorum. Resharing should be used in cases where we aim to modify the current `t-of-n` quorum with a new quorum with `newT-of-newN` signers for the same public key.

This is the method that a new party (meaning one that does not currently have an [Sr25519SecretShare](#type-sr25519secretshare) ) should use for receiving a key share in the new `newT-of-newN` quorum. The method takes the same input parameters as [Sr25519.Keygen](#func-sr25519-keygen) since for a new party joining the quorum the `Reshare` operation is very similar to a `Keygen` operation. In order to receive the [KeygenID](#type-keygenid)-s of parties that are already a part of the quorum, those parties will need to call \[ExportID] and send the result to the parties in the new quorum.

Returns an [Sr25519SecretShare](#type-sr25519secretshare) with the **secret** data that can be used for signing as well as the [Sr25519PublicKey](#type-sr25519publickey).

###### Example

```

const N = 5
const newT = 5
const API_KEY = "MY_API_KEY"
// A signing quorum of `3-of-5` is set up without this party.
// Some time passes...
// Now this party wishes to be part of a new quorum of `5-of-6`.
//
// The app server creates a room for newN(= 6) parties.
sr25519 := NewSr25519("")
reshareRoomUuid, err := sr25519.CreateRoom(N, API_KEY)
if err != nil {
	panic(err)
}

// At least T(= 3) parties now join the reshare room using the current secret key material (this will be done using `ReshareRemainingParty`), all new parties will then join the reshare room using their `KeygenPrivateKey` using `ReshareNewParty`.
keygenID, keygenPrivKey, err := sr25519.InitKeygen()
if err != nil {
	panic(err)
}
// This new party will send its `KeygenID` to all other parties.
// This party will also receive the `KeygenID`s of all other parties of the new quorum.
keygenIds := []KeygenID{"keygenID1", keygenID, "keygenID3", "keygenID4", "keygenID5", "keygenID6"} // Note that here we must include our own `KeygenID` as well, the order of the ids doesn't matter.

// Note: the public key returned here is the same as the one returned by the keygen
newShare, _, err := sr25519.ReshareNewParty(reshareRoomUuid, newT, keygenPrivKey, keygenIds)
if err != nil {
	panic(err)
}
// newShare can now be used for signing under the newT(= 5) threshold with the same public key, as well as be reshared again
_ = newShare

```

<a name="Sr25519.ReshareRemainingParty" />

### func (Sr25519) ReshareRemainingParty

```
func (sr25519 Sr25519) ReshareRemainingParty(roomUuid RoomUUID, newThreshold uint16, share Sr25519SecretShare, keygenIDs []KeygenID) (Sr25519SecretShare, Sr25519PublicKey, error)
```

WARNING: Key resharing is an **advanced** feature of the SDK. We strongly advise consulting with the Sodot team **before** using it, as incorrect usage might lead to the **detriment** of the private key **security**. To use the feature correctly, developers using this feature must make sure that at least `n - t + 1` parties of the `t-of-n` signing quorum delete their current shares before using the resharing of the private key. Also, after resharing, the resharing operation must not be considered complete until such deletion has occurred. Since deleting a share **cannot** be guaranteed cryptographically, it **must** be guaranteed by the software architecture (hence, by the developers using the SDK).

Resharing the **private key** of the `t-of-n` quorum of signers, the resultant key shares will be of the exact **same** public key as the previous quorum. Resharing should be used in cases where we aim to modify the current `t-of-n` quorum with a new quorum with `newT-of-newN` signers for the same public key.

This is the method that a remaining party (meaning one that does currently have a key share) should use for receiving a new key share in the new `newT-of-newN` quorum. The method takes the same input parameters as [Sr25519.ReshareNewParty](#func-sr25519-resharenewparty) except that it will use its existing [Sr25519SecretShare](#type-sr25519secretshare) instead of a new [KeygenPrivateKey](#type-keygenprivatekey). In order to receive the [KeygenID](#type-keygenid)-s of parties that are already a part of the quorum, those parties will need to call \[ExportID] and send the result to the parties in the new quorum.

Returns a new [Sr25519SecretShare](#type-sr25519secretshare) with the **secret** data that can be used for signing as well as the [Sr25519PublicKey](#type-sr25519publickey).

###### Example

```

const N = 5
const newT = 5
const API_KEY = "MY_API_KEY"
// A signing quorum of `3-of-5` is set up with this party.
// secretShare, pk, err := sr25519.Keygen(...)
var secretShare Sr25519SecretShare
//
// Some time passes...
// Now this party wishes to be part of a new quorum of `5-of-6`.
//
// The app server creates a room for newN(= 6) parties.
sr25519 := NewSr25519("")
reshareRoomUuid, err := sr25519.CreateRoom(N, API_KEY)
if err != nil {
	panic(err)
}

// At least T(= 3) parties now join the reshare room using the current secret key material (this will be done using `ReshareRemainingParty`), all new parties will then join the reshare room using their `KeygenPrivateKey` using `ReshareNewParty`.
keygenID, err := sr25519.ExportID(secretShare) // This is a remaining party
if err != nil {
	panic(err)
}

// This remaining party will send its `KeygenID` to all other parties (new - via an authenticated channel and remaining - via any channel).
// This party will also receive the `KeygenID`s of all other parties of the new quorum (new - via an authenticated channel and remaining - via any channel).
keygenIds := []KeygenID{"keygenID1", "keygenID2", keygenID, "keygenID4", "keygenID5", "keygenID6"} // Note that here we must include our own `KeygenID` as well, the order of the ids doesn't matter.

// Note: the public key returned here is the same as the one returned by the keygen
newShare, _, err := sr25519.ReshareRemainingParty(reshareRoomUuid, newT, secretShare, keygenIds)
if err != nil {
	panic(err)
}
// newShare can now be used for signing under the newT(= 5) threshold with the same public key, as well as be reshared again
_ = newShare

```

<a name="Sr25519.Sign" />

### func (Sr25519) Sign

```
func (sr25519 Sr25519) Sign(roomUuid RoomUUID, share Sr25519SecretShare, msg []byte, derivationPath []string) (Sr25519Signature, error)
```

Sign signs a message using an Sr25519SecretShare. Notice that unlike ECDSA, in Sr25519 there's no need to hash the message before signing it. The derivationPath must be a soft sr25519 derivation path to use for signing the message.

###### Example

```

// To sign a message, create a signing room on the server side, using your API_KEY
const T = 2
const API_KEY = "MY_API_KEY"
// An Sr25519SecretShare is generated using Keygen
// secretShare, pk, err := sr25519.Keygen(...)
var secretShare Sr25519SecretShare
sr25519 := NewSr25519("")
signingRoomUuid, err := sr25519.CreateRoom(T, API_KEY)
if err != nil {
	panic(err)
}

// Pick the derivation path of the public key you want to sign for
derivationPath := []string{"this", "is", "a", "derivation", "path"}
// Get the public key for the derivation path
derivedPubKey, err := sr25519.DerivePubkey(secretShare, derivationPath)
if err != nil {
	panic(err)
}
// The derived public key can now be used to verify signatures with the same derivation path
_ = derivedPubKey

// Define the message
message := []byte("my message")
// 2 parties join the signing room
signature, err := sr25519.Sign(signingRoomUuid, secretShare, message, derivationPath)
if err != nil {
	panic(err)
}
// This signature can now be verified against pubkey
_ = signature

```

<a name="Sr25519PublicKey" />

## type Sr25519PublicKey

An Sr25519 public key, generated by the [Sr25519.Keygen](#func-sr25519-keygen) function.

```
type Sr25519PublicKey [32]byte
```

<a name="Sr25519PublicKeyFromString" />

### func Sr25519PublicKeyFromString

```
func Sr25519PublicKeyFromString(s string) (Sr25519PublicKey, error)
```

Sr25519PublicKeyFromString parses a hex string into an Sr25519PublicKey.

<a name="Sr25519PublicKey.String" />

### func (\*Sr25519PublicKey) String

```
func (pubkey *Sr25519PublicKey) String() string
```

String returns the hex representation of the public key.

<a name="Sr25519SecretShare" />

## type Sr25519SecretShare

The per-party **private** key material that is used for threshold signing.

```
type Sr25519SecretShare string
```

<a name="Sr25519SecretShare.Bytes" />

### func (Sr25519SecretShare) Bytes

```
func (share Sr25519SecretShare) Bytes() []byte
```

Bytes returns the raw representation of the Sr25519SecretShare.

<a name="Sr25519Signature" />

## type Sr25519Signature

An Sr25519 signature, generated by the [Sr25519.Sign](#func-sr25519-sign) function.

```
type Sr25519Signature [64]byte
```

<a name="Sr25519Signature.String" />

### func (\*Sr25519Signature) String

```
func (sig *Sr25519Signature) String() string
```

String returns the hex representation of the signature.
