tandem_http_client 0.3.0

HTTP client for the Tandem SMPC engine
Documentation
<html>

<head>
  <meta content="text/html;charset=utf-8" http-equiv="Content-Type" />
  <link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/codemirror.min.css"
    integrity="sha512-uf06llspW44/LZpHzHT6qBOIVODjWtv4MxCricRxkzvopAlSWnTf6hpZTFxuuZcuNE9CBQhqE0Seu1CoRk84nQ=="
    crossorigin="anonymous" referrerpolicy="no-referrer" />
  <link href="https://uploads-ssl.webflow.com/6262a2a7735ff102899431ef/6262a2a7735ff1a94d943269_SINE_Favicon.png"
    rel="shortcut icon" type="image/x-icon">
  <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/codemirror.min.js"
    integrity="sha512-xwrAU5yhWwdTvvmMNheFn9IyuDbl/Kyghz2J3wQRDR8tyNmT8ZIYOd0V3iPYY/g4XdNPy0n/g0NvqGu9f0fPJQ=="
    crossorigin="anonymous" referrerpolicy="no-referrer"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/addon/mode/simple.min.js"
    integrity="sha512-9YoNYsegWvbA5aiSshQ2BNW2FAq3CQVLqpg2r6urw9Tfl1GklM9PNgrMRVz8fhEtjM+uZfO/1X3RURkMcil8wg=="
    crossorigin="anonymous" referrerpolicy="no-referrer"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/mode/rust/rust.min.js"
    integrity="sha512-g3Nhw36S0p4ZJQcky87D5M+vZbFvLrgsHWYltUy5IW0zKbvi8GlPRjJSo2CyUyQiU01Ier7u+rBABDs3BawKyQ=="
    crossorigin="anonymous" referrerpolicy="no-referrer"></script>
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/theme/nord.min.css"
    integrity="sha512-sPc4jmw78pt6HyMiyrEt3QgURcNRk091l3dZ9M309x4wM2QwnCI7bUtsLnnWXqwBMECE5YZTqV6qCDwmC2FMVA=="
    crossorigin="anonymous" referrerpolicy="no-referrer" />
  <style>
    .CodeMirror {
      height: fit-content;
    }
  </style>
</head>

<body class="bg-gray-300">
  <div class="w-full max-w-5xl mx-auto py-4">
    <div>
      <a href="https://sine.foundation" target="_blank"><img src="./assets/SINE_logo.png" alt="SINE Foundation"
          class="h-8 md:h-10 mx-auto my-8"></a>
      <form class="playground-cell bg-white shadow-md rounded px-6 pt-6 pb-6">
        <div class="pb-6 text-center">
          <h1 class="text-lg">Playground for <a href="https://sine.foundation/library/002-smpc" alt="Secure
          Multi-Party Computation" style="text-decoration: underline #fef08a; text-decoration-thickness: 4px;">Secure
              Multi-Party
              Computation</a> using SINE's <a href="https://github.com/sine-fdn/tandem"
              style="text-decoration: underline #fef08a; text-decoration-thickness: 4px;">Tandem engine</a>.
          </h1>
        </div>
        <div class="md:flex mb-4">
          <div
            class="playground-source-code-container text-sm shadow appearance-none border rounded w-full text-gray-700 leading-tight focus:outline-none focus:shadow-outline">
            <textarea class="playground-source-code" name="source-code" rows="8" cols="100">
// All programs must be written in Garble.
// See https://github.com/sine-fdn/garble-lang

pub fn main(a: i32, b: i32) -> i32 {
    a + b
}</textarea>
          </div>
        </div>
        <div class="mb-4">
          <fieldset class="flex border shadow appearance-none rounded w-full py-2 px-3 text-gray-700 leading-tight">
            <div class="text-gray-500">MPC Server</div>
            <div class="form-check form-check-inline px-2">
              <input
                class="form-check-input rounded-full h-4 w-4 border border-gray-300 bg-white checked:bg-blue-600 checked:border-blue-600 focus:outline-none transition duration-200 mt-1 align-top bg-no-repeat bg-center bg-contain float-left mr-2 cursor-pointer"
                type="radio" name="serverUrlRadioOptions" id="radioRemote" value="https://echo-server.sine.dev" checked>
              <label class="form-check-label inline-block text-gray-800"
                for="inlineRadio10">https://echo-server.sine.dev</label>
            </div>
            <div class="form-check form-check-inline">
              <input
                class="form-check-input rounded-full h-4 w-4 border border-gray-300 bg-white checked:bg-blue-600 checked:border-blue-600 focus:outline-none transition duration-200 mt-1 align-top bg-no-repeat bg-center bg-contain float-left mr-2 cursor-pointer"
                type="radio" name="serverUrlRadioOptions" id="radioLocal" value="http://localhost:8000">
              <label class="form-check-label inline-block text-gray-800"
                for="inlineRadio10">http://localhost:8000</label>
            </div>
          </fieldset>
        </div>
        <div class="mb-4">
          <input
            class="playground-function-name shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"
            type="text" placeholder="Function to Execute">
        </div>
        <div class="mb-4">
          <input
            class="playground-plaintext-metadata shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"
            type="text" placeholder="Metadata (Plaintext)">
        </div>
        <div class="mb-4">
          <input
            class="playground-private-input shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"
            type="text" placeholder="Input (Kept Private)">
        </div>
        <div class="md:flex md:items-center">
          <div class="pr-4">
            <button
              class="playground-btn-compute bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-2 rounded focus:outline-none focus:shadow-outline inline-flex items-center"
              type="button">
              Compute
            </button>
          </div>
          <div class="playground-output-div hidden md:flex md:items-center" class="mb-4">
            <svg class="playground-spinner hidden animate-spin h-10 w-10 text-blue-500"
              xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
              <circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4">
              </circle>
              <path class="opacity-75" fill="currentColor"
                d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z">
              </path>
            </svg>
            <pre style="white-space: pre-wrap"
              class="font-mono appearance-none rounded w-full py-2 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"><code class="playground-output" name="source-code"></code></pre>
          </div>
        </div>
        <p class="text-center text-gray-500 text-xs">
          SMPC Engine WASM Notebook by <a class="text-blue-400 hover:text-blue-500 transition duration-300 ease-in-out"
            href="https://sine.foundation/">SINE Foundation e.V.</a>
        </p>
    </div>
    <!-- Note the usage of `type=module` here as this is an ES6 module -->
    <script type="module">
      import init, { MpcProgram, MpcData, compute } from './pkg/tandem_http_client.js';

      const code_mirror_config = {
        lineNumbers: true,
        mode: "rust",
        theme: "nord",
      };

      const source_code_area = document.getElementsByClassName("playground-source-code")[0];
      const editor = CodeMirror.fromTextArea(source_code_area, code_mirror_config);
      const cell = document.getElementsByClassName("playground-cell")[0];

      const addCellListeners = (cell, editor) => {
        const spinner = cell.getElementsByClassName("playground-spinner")[0];
        const btn_compute = cell.getElementsByClassName("playground-btn-compute")[0];
        const output_div = cell.getElementsByClassName("playground-output-div")[0];
        btn_compute.addEventListener("click", async function () {
          let radioButtons = document.getElementsByName('serverUrlRadioOptions');

          let url = "";
          for (let radio of radioButtons) {
            if (radio.checked) {
              url = radio.value;
            }
          }
          const source_code = editor.getValue();
          const function_name = cell.getElementsByClassName("playground-function-name")[0].value;
          const my_input = cell.getElementsByClassName("playground-private-input")[0].value;
          const plaintext_metadata = cell.getElementsByClassName("playground-plaintext-metadata")[0].value;
          spinner.classList.remove("hidden");
          btn_compute.classList.add("cursor-not-allowed");
          btn_compute.classList.add("opacity-50");
          btn_compute.disabled = true;

          let is_success = false;
          const output = cell.getElementsByClassName("playground-output")[0];
          output.classList.add("hidden");
          try {
            const t0 = performance.now();

            const mpc_program = new MpcProgram(source_code, function_name);
            const info_about_gates = mpc_program.report_gates();
            const t1 = performance.now();

            const mpc_input = MpcData.from_string(mpc_program, my_input);
            const result = (await compute(url, plaintext_metadata, mpc_program, mpc_input)).to_literal_string();
            const t2 = performance.now();

            console.log(`Compilation: ${((t1 - t0) / 1000).toFixed(2)}s, MPC: ${((t2 - t1) / 1000).toFixed(2)}s, for ${info_about_gates}`);

            output.innerHTML = result;
            output.classList.remove("border-red-500");
            output.classList.remove("text-red-500");
            is_success = true;
          } catch (e) {
            output.innerHTML = e;
            output.classList.add("border-red-500");
            output.classList.add("text-red-500");
          } finally {
            output.classList.remove("hidden");
            output_div.classList.remove("hidden");
            spinner.classList.add("hidden");
            btn_compute.classList.remove("cursor-not-allowed");
            btn_compute.classList.remove("opacity-50");
            btn_compute.disabled = false;
          }
        });
      };

      init().then(() => {
        console.log("Ready for running Secure Multi-Party Computation from WASM...");
        addCellListeners(cell, editor);
      });
    </script>
</body>

</html>