Non-Custodial Wallet

In the non-custodial wallet model, Secubit provides secure infrastructure but does not hold the entire signing key. Instead, the key is divided into cryptographic shares using Multi-Party Computing (MPC). One share remains inside the Secubit HSM, while the other shares are distributed to client users. This ensures that no single party β€” not even Secubit β€” ever has the full key, and every transaction requires collaboration.

Each user holds two components: an approving private key and a signing key share. The approving private key is used to authorize requests, protected by PassKey or biometrics on the user’s device Secure Element. The signing key share participates in the MPC signing process, where users generate partial signatures without ever reconstructing the complete key.

When a transaction is requested, each user must first approve the request with their approving private key. Then, their signing key share contributes a partial signature. All of These partial signatures are equal, and one of them will be used as signature share A.

Inside the HSM, the Vault verifies that the required threshold of user approvals has been satisfied. If valid, the HSM uses its own signing key share to produce another partial signature, signature share B. Finally, the HSM combines signature share A (from the client) and signature share B (from the HSM) into the complete transaction signature.

This workflow guarantees that:

  1. Users retain direct control over their key shares, ensuring self-sovereignty.
  2. Threshold approvals must be satisfied before the HSM contributes its share.
  3. The full private key is never reconstructed, only the final transaction signature is produced.

The non-custodial model provides the highest degree of client control, while still leveraging Secubit’s HSM network for secure enforcement, auditability, and policy integration.

flowchart
    R["request"]
    R --> U1
    R --> U2
    R --> U3
    R --> SB

    subgraph U1["User 1"]
        AK1("πŸ”‘ approving </br> privkey 1")
        AK1 --> S1
        S1(["sign"])

        SK1("πŸ”‘ signing </br> key share A")
        SK1 --> SA1
        SA1(["mpc sign"])
    end
    S1 --> A1 --> V1
    A1["approval 1"]
    SA1 -.-> SIG_A

   subgraph U2["User 2"]
        AK2("πŸ”‘ approving </br> privkey 2")
        AK2 --> S2
        S2(["sign"])

        SK2("πŸ”‘ signing </br> key share A")
        SK2 --> SA2
        SA2(["mpc sign"])
    end
    S2 --> A2 --> V2
    A2["approval 2"]
    SA2 -.-> SIG_A

    subgraph U3["User 3"]
        AK3("πŸ”‘ approving </br> privkey 3")
        AK3 --> S3
        S3(["sign"])

        SK3("πŸ”‘ signing </br> key share A")
        SK3 --> SA3
        SA3(["mpc sign"])
    end
    S3 --> A3 --> V3
    A3["approval 3"]
    SA3 -.-> SIG_A

    SIG_A["signature share A"]

    subgraph HSM["Secubit HSM"]
        SK("πŸ”‘ signing key share B")
        SK --> SB
        SB(["mpc sign"])

        V1{"verify?"}
        V1 --> TH

        V2{"verify?"}
        V2 --> TH

        V3{"verify?"}
        V3 --> TH

        TH{"threshold?"}
        TH --> SB --> SIG_B

        SIG_B["signature share B"]
        SIG_B --> C

        C(["mpc combine"])
    end

    SIG_A --> C --> T
    T["transaction"]