HaLo
Sending a Command

Sending a Command

The user is able to execute a command -- such as sign a message using one of the available keys -- through one of several interfaces including a proprietary browser interface, NDEF and ADPU. The HaLo expects 32 byte digests which have been hashed client side (e.g. using sha256 or keccak256). We recommend using LibHaLo (opens in a new tab) to interface with HaLos on mobile web, in React Native apps and CLIs.

Signature Types

By default, HaLos can produce any secp256k1 signature including potentially malleable signatures. HaLo signatures are not implicitly formatted to any Ethereum format, however, you can generate signatures of any desired format such as those required for an Ethereum transaction, EIP-191 and EIP-712.

It's important to understand which kind of signature you want to generate as this influences the digest presented to a chip, for instance by including an EIP-191 (opens in a new tab) compliant message header or EIP-712 (opens in a new tab) schema. Once a signature type is chosen, keep in mind that the client must hash the message with a desired hashing scheme as the HaLo does not carry out any hashing.

Using LibHaLo

LibHaLo is a node library designed to abstract away low level interfaces allowing apps to execute commands from a variety of environments. See the LibHaLo repo (opens in a new tab) for more information on how to execute commands against HaLos.

Mobile Browser Example

Include the libhalo.js on your webpage:

<script src="libhalo.js"></script>

Create a minimal user interface:

<div id="statusText">Please click on the button below.</div>
<button onclick="btnPressed();">Click here</button>

Call the library inside the button click routine:

async function btnPressed() {
    let command = {
        name: "sign",
        keyNo: 1,
        digest: "6e76e202b71892e9ee32a634eefcf522ba1c4cb4eadd7e4562ced1270214c41e"
    };
    
    document.getElementById('statusText').innerText = "Please tap NFC tag to the back of your smartphone...";
 
    try {
        let res = await execHaloCmdWeb(command);
        // display operation result
        document.getElementById('statusText').innerText = JSON.stringify(res, null, 4);
    } catch (e) {
        // display error
        document.getElementById('statusText').innerText = e;
    }
}

Load the webpage through HTTPS on a mobile browser like iOS Safari or Android Chrome and tap Click here to initiate a scan. You can use a tool like localtunnel (opens in a new tab) to serve a locally hosted page over HTTPS.

Manually Constructing a Command

You can easily craft an NDEF message to send a signing request

  1. Prepare a NDEF message with one record and a desired $CHALLENGE to be signed by the HaLo. A $CHALLENGE should mirror the cmd param but with the desired key slot, command type and digest:
{ recordType: "unknown", data: $CHALLENGE }
  1. Write the message to the chip using standard writing method as described in NFC Forum Type 4 Tag specification. Depending on the platform and interface there may be explicit NDEF write commands available (opens in a new tab) or you may need to construct the write using lower-level ADPU commands.
  2. Perform NDEF read. The chip will return a single NDEF record containing the URL.
  3. Parse URL’s cmd field and verify whether it contains the command input in step #1.
  4. Parse URL’s res field to obtain the command execution result.
  5. Verify ECDSA signature.

See the halo-webnfc-demo for an example HaLo web app which signs a randomly generated challenge using key slot #1.