{
  "openapi": "3.1.1",
  "info": {
    "title": "Shamir Secret Sharing API",
    "version": "1.0.0",
    "summary": "Split a secret into n shares so any k recover it, and combine shares, locally.",
    "description": "Every endpoint performs the same calculation as the human page and returns inputs, result, units, assumptions, sources, warnings and computedAt. MCP endpoint: /mcp."
  },
  "servers": [
    {
      "url": "https://shamirsecretsharing.usefulweb.site"
    }
  ],
  "paths": {
    "/api/v1/calculate": {
      "post": {
        "operationId": "calculate",
        "summary": "Split a secret into n shares so any k recover it, and combine shares, locally.",
        "description": "Splits a secret (recovery code, password, key) into n shares with a threshold k using Shamir's scheme over GF(256): any k shares reconstruct it, fewer reveal nothing. Combines and verifies shares with an optional checksum. With JavaScript on, splitting and combining happen in your browser.\n\nMethodology:\n- Each byte of the secret is the constant term of its own random polynomial of degree k−1 over GF(2^8) (field polynomial x^8+x^4+x^3+x+1, as in AES). Share i holds the value of every polynomial at x = i (i = 1…n), so a share is as long as the secret.\n- Combining uses Lagrange interpolation at x = 0. Any k shares give the secret; with k−1 or fewer, every possible secret is equally consistent with the shares (information-theoretic security).\n- Optional checksum: the first 4 bytes of SHA-256(secret) are appended before splitting. After combining, a wrong share or too few shares are detected with probability 1 − 2^−32.\n- Shares are written as \"<index>-<data>\" in hex or Base64. The format is not interchangeable with other tools (e.g. ssss-split, which uses a larger field).\n- With JavaScript on, the page splits and combines in your browser with crypto.getRandomValues; the secret is not sent to the server. Without JavaScript or via the API the server does it with Node.js crypto and does not store anything.\n\nStore shares in different places and test recovery before relying on them. Anyone holding k shares can recover the secret.",
        "tags": [
          "crypto"
        ],
        "x-mcp-tool": "shamir_secret_sharing",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ShamirSecretSharingInput"
              },
              "examples": {
                "example1": {
                  "summary": "Split a recovery code into 5 shares, any 3 recover it (demo seed)",
                  "value": {
                    "action": "split",
                    "secret": "correct horse battery staple",
                    "shares": 5,
                    "threshold": 3,
                    "seed": "demo"
                  }
                },
                "example2": {
                  "summary": "Combine 3 shares",
                  "value": {
                    "action": "combine",
                    "format": "hex",
                    "threshold": 3,
                    "sharesInput": "1-ee23a34dc787be4d8af7916bb9d669417a54d63602154ed4db2ff116b421013a\n3-ac721e5b9f43f6ca6776a86e6d38d61c86b773028d0747eaa1987125c62a63f5\n5-7d88d2da6b481f3783705eb5cd759e8f3433ca98f8ca8b277b7e58092ea75c9d"
                  }
                },
                "example3": {
                  "summary": "Split into 3 Base64 shares, 2 needed (demo seed)",
                  "value": {
                    "action": "split",
                    "secret": "vault unseal key 42",
                    "shares": 3,
                    "threshold": 2,
                    "format": "base64",
                    "seed": "example"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ShamirSecretSharingResult"
                }
              }
            }
          },
          "400": {
            "description": "Malformed JSON body.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "422": {
            "description": "Invalid input (see errors[]).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (see Retry-After).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/tool": {
      "get": {
        "operationId": "getToolDefinition",
        "summary": "Inputs, output schema and examples for this tool",
        "responses": {
          "200": {
            "description": "Tool definition.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Problem": {
        "type": "object",
        "description": "RFC 9457 problem details. 422 responses include per-field `errors`.",
        "required": [
          "type",
          "title",
          "status",
          "detail"
        ],
        "properties": {
          "type": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "status": {
            "type": "integer"
          },
          "detail": {
            "type": "string"
          },
          "code": {
            "type": "string"
          },
          "errors": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "field",
                "message"
              ],
              "properties": {
                "field": {
                  "type": "string"
                },
                "message": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "ShamirSecretSharingInput": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "action": {
            "title": "Action",
            "type": "string",
            "enum": [
              "split",
              "combine"
            ],
            "default": "split"
          },
          "secret": {
            "title": "Secret (split)",
            "description": "Text up to 10,000 characters (UTF-8).",
            "type": "string",
            "maxLength": 10000
          },
          "shares": {
            "title": "Number of shares (n)",
            "type": "integer",
            "minimum": 2,
            "maximum": 255,
            "default": 5
          },
          "threshold": {
            "title": "Threshold (k shares needed)",
            "description": "Split: any k shares recover the secret. Combine: used to check extra shares for consistency.",
            "type": "integer",
            "minimum": 2,
            "maximum": 255,
            "default": 3
          },
          "format": {
            "title": "Share format",
            "type": "string",
            "enum": [
              "hex",
              "base64"
            ],
            "default": "hex"
          },
          "checksum": {
            "title": "Add a 4-byte SHA-256 checksum so wrong or too few shares are detected",
            "type": "boolean",
            "default": true
          },
          "sharesInput": {
            "title": "Shares (combine), one per line",
            "type": "string",
            "maxLength": 200000
          },
          "seed": {
            "title": "Demo seed (optional, reproducible — never for real secrets)",
            "description": "Split only. With a seed the shares are predictable; leave empty for real use.",
            "type": "string",
            "maxLength": 200
          }
        },
        "required": []
      },
      "ShamirSecretSharingResult": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "schemaVersion",
          "tool",
          "computedAt",
          "inputs",
          "summary",
          "result",
          "units",
          "assumptions",
          "sources",
          "warnings",
          "presentation",
          "links"
        ],
        "properties": {
          "schemaVersion": {
            "type": "string",
            "const": "1.0"
          },
          "tool": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "id",
              "name",
              "version"
            ],
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "version": {
                "type": "string"
              }
            }
          },
          "computedAt": {
            "type": "string",
            "format": "date-time"
          },
          "inputs": {
            "type": "object",
            "description": "Normalised inputs actually used, including applied defaults."
          },
          "summary": {
            "type": "string"
          },
          "result": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "action",
              "format",
              "checksum"
            ],
            "properties": {
              "action": {
                "type": "string",
                "enum": [
                  "split",
                  "combine"
                ]
              },
              "format": {
                "type": "string",
                "enum": [
                  "hex",
                  "base64"
                ]
              },
              "checksum": {
                "type": "boolean"
              },
              "shareCount": {
                "type": "integer"
              },
              "threshold": {
                "type": "integer"
              },
              "secretBytes": {
                "type": "integer"
              },
              "shareBytes": {
                "type": "integer"
              },
              "shares": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "seeded": {
                "type": "boolean"
              },
              "sharesUsed": {
                "type": "array",
                "items": {
                  "type": "integer"
                }
              },
              "secretText": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Recovered secret as UTF-8 text (null if not valid UTF-8)."
              },
              "secretHex": {
                "type": "string"
              },
              "checksumValid": {
                "type": [
                  "boolean",
                  "null"
                ]
              },
              "consistent": {
                "type": [
                  "boolean",
                  "null"
                ],
                "description": "Extra shares beyond the threshold lie on the same polynomial (null if not checkable)."
              }
            }
          },
          "units": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "assumptions": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "sources": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "title"
              ],
              "properties": {
                "title": {
                  "type": "string"
                },
                "url": {
                  "type": "string"
                },
                "publisher": {
                  "type": "string"
                },
                "retrievedAt": {
                  "type": "string"
                },
                "note": {
                  "type": "string"
                }
              }
            }
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "presentation": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "Display blocks used by the human page (same data)."
          },
          "links": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "human",
              "api",
              "openapi",
              "methodology"
            ],
            "properties": {
              "human": {
                "type": "string",
                "format": "uri"
              },
              "api": {
                "type": "string",
                "format": "uri"
              },
              "openapi": {
                "type": "string",
                "format": "uri"
              },
              "methodology": {
                "type": "string",
                "format": "uri"
              }
            }
          }
        }
      }
    }
  }
}