# Getting Started

Generate a key and begin signing in under a minute.

## Key Generation

First we must generate a public key and some key shares so that we can later sign messages.\
You will need your `API_KEY`.

We show example code for a 2-of-3 threshold signing scenario.\
(Note that Sodot MPC SDK allows any t-of-n [threshold signing](/cryptography/signature-scheme#what-is-a-threshold-signature-scheme) setting)

To generate a key we simply run:

:::tip[Feature]
BIP-340 (for Bitcoin Taproot) is also supported.
:::

<Tabs>
  <Tab title="ECDSA Go">
    ```go
    import "github.com/sodot-rs/sodot-go-sdk"

    // 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 := sodot.NewEcdsa("")
    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 := []sodot.KeygenID{"keygenID1", "keygenID2"}
    // All parties join the keygen room
    // Discard the keygenPrivKey at this point
    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

    // 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
    ```

    :::tip[API reference]
    Full details can be found [here](/go/api-ref#type-ecdsa).
    :::
  </Tab>

  <Tab title="Ed25519 Go">
    ```go
    import "github.com/sodot-rs/sodot-go-sdk"

    // 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 := sodot.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 := []sodot.KeygenID{"keygenID1", "keygenID2"}
    // All parties join the keygen room
    // Discard the keygenPrivKey at this point
    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

    // 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
    ```

    :::tip[API reference]
    Full details can be found [here](/go/api-ref#type-ed25519).
    :::
  </Tab>
</Tabs>

Behind the scenes this is the rough flow of communication that occurs:

```mermaid
sequenceDiagram
    actor Alice
    actor Bob
    actor Charlie
    participant App as App Server
    rect rgb(200,200,230,.3)
    Note left of Alice: Keygen Setup
    App->>Relay: Create room for 3 participants
    Relay->>App: room_id
    App->>Alice: room_id
    App->>Bob: room_id
    App->>Charlie: room_id
    par Alice handshakes w/ Bob
    Note over Alice,Bob: Propagated externally to the SDK 
    Alice-->>Bob: keygen_id
    Bob-->>Alice: keygen_id
    and Alice handshakes w/ Charlie
    Note over Alice,Charlie: Propagated externally to the SDK
    Alice-->>Charlie: keygen_id
    Charlie-->>Alice: keygen_id
    and Bob handshakes w/ Charlie
    Note over Bob,Charlie: Propagated externally to the SDK
    Bob-->>Charlie: keygen_id
    Charlie-->>Bob: keygen_id
    end
    Alice->>Relay: Connect to room_id
    Bob->>Relay: Connect to room_id
    Charlie->>Relay: Connect to room_id
    end
    rect rgb(200,230,200,.3)
    Note left of Alice: Key Generation
    Note over Alice,Charlie: Run Distributed Key Generation
    activate Alice
    activate Bob
    activate Charlie
    Alice->>Relay: Relayed Communication
    Relay->>Alice: 
    Bob->>Relay: 
    Relay->>Bob: 
    Charlie->>Relay: 
    Relay->>Charlie: 
    Note over Alice: Alice has a Key Share
    deactivate Alice
    Note over Bob: Bob has a Key Share
    deactivate Bob
    Note over Charlie: Charlie has a Key Share
    deactivate Charlie
    end

```

## Signing

Now that we have key shares on all the devices/servers of the potential signers we can sign by running:

<Tabs>
  <Tab title="ECDSA Go">
    ```go
    import (
    	"github.com/kaspanet/go-secp256k1"
    	"github.com/sodot-rs/sodot-go-sdk"
    )

    // 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 was generated using Keygen
    // secretShare, pk, err := ecdsa.Keygen(...)
    var secretShare sodot.EcdsaSecretShare
    ecdsa := sodot.NewEcdsa("")
    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)
    }
    // Hash the message
    messageHash := sodot.MessageHashFromSha256([]byte("my message"))
    // 2 parties join the signing room
    signature, err := ecdsa.Sign(signingRoomUuid, secretShare, messageHash, derivationPath)
    if err != nil {
    	panic(err)
    }

    // Create a signature and public key according to kaspanet/go-secp256k1's format
    serializedSignature := append(signature.R(), signature.S()...)
    deserializedSignature, _ := secp256k1.DeserializeECDSASignature((*secp256k1.SerializedECDSASignature)(serializedSignature))
    compressedPk := derivedPubKey.SerializeCompressed()
    pubKey, _ := secp256k1.DeserializeECDSAPubKey(compressedPk[:])
    hash := secp256k1.Hash(messageHash)
    // Validate the signature
    isValid := pubKey.ECDSAVerify(&hash, deserializedSignature)
    _ = isValid
    ```

    Full library documentation can be found [here.](https://pkg.go.dev/github.com/kaspanet/go-secp256k1@v0.0.7)
  </Tab>

  <Tab title="Ed25519 Go">
    ```go
    import (
    	"crypto/ed25519"

    	"github.com/sodot-rs/sodot-go-sdk"
    )

    // 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 was generated using Keygen
    // secretShare, pk, err := sodotEd25519.Keygen(...)
    var secretShare sodot.Ed25519SecretShare
    // Name the sodot SDK variable sodotEd25519 so it is not confused with the crypto/ed25519 package
    sodotEd25519 := sodot.NewEd25519("")
    signingRoomUuid, err := sodotEd25519.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 := sodotEd25519.DerivePubkey(secretShare, derivationPath)
    if err != nil {
        panic(err)
    }

    // Define the message
    message := []byte("my message")
    // 2 parties join the signing room
    signature, err := sodotEd25519.Sign(signingRoomUuid, secretShare, message, derivationPath)
    if err != nil {
        panic(err)
    }
    // Validate the signature using the standard library's crypto/ed25519 package
    isValid := ed25519.Verify(derivedPubKey[:], message, signature[:])
    _ = isValid
    ```

    Full library documentation can be found [here.](https://pkg.go.dev/crypto/ed25519)
  </Tab>
</Tabs>

Behind the scenes this is the rough flow of communication that occurs. Note that since only 2 signers are needed, Alice (chosen as a non-signer in this example) doesn't participate at all in the protocol:

```mermaid
sequenceDiagram
    actor Alice
    actor Bob
    actor Charlie
    participant App as App Server
    rect rgb(200,200,230,.3)
    Note left of Alice: Room Setup
    App->>Relay: Create room for 2 participants
    Relay->>App: room_id
    App->>Bob: room_id
    App->>Charlie: room_id
    par Bob invites Charlie
    Note over Bob,Charlie: Propagated externally to the SDK
    Bob-->>Charlie: msg
    Note over Charlie: Charlie decides whether they wish to sign msg
    end
    Bob->>Relay: Connect to room_id
    Charlie->>Relay: Connect to room_id
    end
    rect rgb(230,200,200,.3)
    Note left of Alice: Signing
    Note over Bob,Charlie: Run Signing
    activate Bob
    activate Charlie
    Bob->>Relay: Relayed Communication
    Relay->>Bob: 
    Charlie->>Relay: 
    Relay->>Charlie: 
    Note over Bob: Bob has a signature on msg
    deactivate Bob
    Note over Charlie: Charlie has a signature on msg
    deactivate Charlie
    end
```
