npm package: @huitl/sdk
Description: NTAG 424 DNA cryptographic verification SDK — parse, decrypt, and verify NFC SUN messages
Author: Fabio Seva
Latest version: 0.3.1

# @huitl/sdk

Built by [HUITL Protocol](https://huitlprotocol.com) — the open verification standard for physical objects.

HUITL Protocol proves physical objects are real using standard NFC chips. Every tap produces a unique, one-time cryptographic signature that can never be replicated or reused. This SDK is the core of the protocol — MIT-licensed, zero runtime dependencies, production-ready.

The cheapest, simplest path from NFC chip tap to cryptographic proof. Standard hardware. Open protocol. Developer-first.

Created by **Fabio Seva** — founder of HUITL Protocol.

For questions, partnerships, or enterprise inquiries: [seva@huitlprotocol.com](mailto:seva@huitlprotocol.com)

### Use Cases & Templates

| Use Case | Description | Template | Status |
|----------|-------------|----------|--------|
| **Product Authentication** | Luxury goods, pharma, wine & spirits, electronics | [`huitl-template-auth`](https://github.com/fspseva/huitl-template-auth) | Live |
| **Digital Product Passport** | EU DPP compliance (batteries Feb 2027, textiles 2027) | `huitl init --template dpp` | Coming soon |
| **Ticketing & Membership** | Event tickets and membership cards that can't be duplicated | `huitl init --template ticketing` | Coming soon |
| **Proof of Presence** | Retail, events, tourist sites — no GPS spoofing possible | `huitl init --template presence` | Coming soon |
| **Anti-Counterfeiting** | Supply chain verification at every touchpoint | `huitl init --template anti-counterfeit` | Coming soon |

## Try It Now

No chips, no hardware, no setup:

```bash
npm install -g @huitl/sdk

huitl verify "https://huitlprotocol.com/tap?picc_data=2C309D265CFFD369A4B62C6B9F40B669&cmac=6A6595D519DF58BF" --key 00000000000000000000000000000000
```

```json
{ "valid": true, "uid": "04112233445566", "readCounter": 42 }
```

That's a real cryptographic verification — the same math that runs on every NFC tap. The URL contains an encrypted chip identity and a one-time signature. The SDK decrypts, derives a session key, and validates the CMAC.

## Installation

```bash
npm install @huitl/sdk
```

## Quick Start

```typescript
import { parseSunMessage, verifySun } from "@huitl/sdk";

// When a user taps an NFC chip, their phone opens a URL like:
// https://yourapp.com/tap?picc_data=EF963FF7828658A599F3041510671E88&cmac=94EED9EE65337086

const sdmKey = Buffer.from("00000000000000000000000000000000", "hex");
const tapUrl = "https://yourapp.com/tap?picc_data=EF963FF7...&cmac=94EED9EE...";

const parsed = parseSunMessage(tapUrl);
const result = verifySun(sdmKey, parsed.encPiccData, parsed.cmac, parsed.macInput);

console.log(result);
// { valid: true, uid: "04112233445566", readCounter: 42 }
```

## API Reference

### `parseSunMessage(url: string): SunMessage`

Parse a SUN message URL from an NTAG 424 DNA chip tap.

```typescript
const { encPiccData, cmac, macInput } = parseSunMessage(url);
```

### `verifySun(sdmKey, encPiccData, cmac, macInput): VerifyResult`

Full end-to-end SUN verification: decrypts PICC data, derives session key, computes and compares CMAC using `crypto.timingSafeEqual`.

```typescript
const result = verifySun(sdmKey, encPiccData, cmac, macInput);
// { valid: boolean, uid: string, readCounter: number }
```

### `decryptPiccData(key: Buffer, enc: Buffer): PiccData`

Decrypt encrypted PICC data (AES-128-CBC, zero IV) to extract the chip UID and read counter.

### `deriveSessionKey(sdmKey, uid, counter, isMac): Buffer`

Derive a session key for SDM MAC or ENC operations per NXP AN12196.

### `aesCmac(key: Buffer, msg: Buffer): Buffer`

Compute AES-CMAC per RFC 4493.

## CLI

### `huitl verify <url> --key <hex>`

Verify a SUN message URL. Outputs JSON, exits 0 if valid.

```bash
huitl verify "https://example.com/tap?picc_data=...&cmac=..." --key 00000000000000000000000000000000
```

### `huitl keygen [--count N]`

Generate random AES-128 key + UID pairs for testing.

```bash
huitl keygen
# { "uid": "04A1B2C3D4E5F6", "aesKey": "1234567890ABCDEF1234567890ABCDEF" }

huitl keygen --count 5
# [ { "uid": "...", "aesKey": "..." }, ... ]
```

### `huitl dev --local`

Start a local development server with SQLite for testing NFC verification.

```bash
huitl dev --local
# Server running at http://localhost:3000
# Tap URL: http://localhost:3000/tap?picc_data=<32hex>&cmac=<16hex>
```

Endpoints:
- `GET /tap?picc_data=...&cmac=...` — Verify a tap
- `GET /api/chips` — List registered test chips
- `POST /api/chips` — Register a test chip `{ "uid": "...", "aesKey": "...", "name": "..." }`

### `huitl provision`

Provision an NTAG 424 DNA chip — writes AES key + SUN configuration.

**Requirements:** PC/SC compatible NFC reader + `npm install -g nfc-pcsc`

**With HUITL Cloud (default):**
```bash
huitl login --api-key <your-key>
huitl provision --name "My Product"
# Place chip on reader → done
```

**Local mode:**
```bash
huitl provision --local --key 00000000000000000000000000000000
```

**Browser UI (batch provisioning):**
```bash
huitl provision --ui
# Opens http://localhost:4000 — provision chips with a visual interface
# Auto-increment naming, session history, CSV export
```

### `huitl login`

Authenticate with HUITL Cloud.

```bash
# Get your API key at https://huitl-cloud.vercel.app/api/auth/google
huitl login --api-key <your-key>
```

### `huitl init [directory]`

Scaffold a new HUITL project from a starter template.

```bash
huitl init my-app
cd my-app && npm install
```

### Supported NFC Readers

| Reader | USB | Price | Notes |
|--------|-----|-------|-------|
| **ACR122U** | USB-A | ~$25 | Most common, recommended |
| ACR1252U | USB-C | ~$35 | USB-C version |
| HID OMNIKEY 5022 | USB-A | ~$40 | Enterprise-grade |
| Identiv uTrust 3700F | USB-A | ~$45 | Also supports HF |

**Does NOT work:** RC522 (SPI, no APDU), phone NFC (no raw APDU on iOS), UID-only readers.

## Types

```typescript
interface PiccData {
  uid: string;        // 7-byte UID as uppercase hex
  readCounter: number; // SDM read counter
}

interface VerifyResult {
  valid: boolean;
  uid: string;
  readCounter: number;
}

interface SunMessage {
  encPiccData: Buffer; // Encrypted PICC data (16 bytes)
  cmac: Buffer;        // Truncated CMAC (8 bytes)
  macInput: Buffer;    // URL portion used as MAC input
}
```

## How It Works

1. An NTAG 424 DNA chip is configured with an AES-128 key and SUN (Secure Unique NFC) messaging
2. When tapped, the chip produces a URL containing encrypted PICC data and a CMAC signature
3. The PICC data contains the chip's unique 7-byte UID and a rolling read counter
4. A session key is derived from the SDM key, UID, and counter
5. The CMAC is computed over the URL content using the session key
6. Verification checks: correct decryption, valid CMAC, and counter increment (anti-replay)

Each tap produces a unique, cryptographically bound message that cannot be replicated or replayed.

## Architecture

```
┌──────────────────────────────────────┐
│           Your Application           │
└──────────────────┬───────────────────┘
                   │ uses
┌──────────────────▼───────────────────┐
│             @huitl/sdk               │
│  parseSunMessage() │ verifySun()     │
│  decryptPiccData() │ deriveSessionKey │
│  aesCmac()         │ TypeScript types │
│              MIT Licensed            │
└──────────────────────────────────────┘
```

## HUITL Ecosystem

| Repo | Description |
|------|-------------|
| **[@huitl/sdk](https://github.com/fspseva/huitl-sdk)** | Open-source SDK + CLI (this repo) |
| **[HUITL Cloud](https://github.com/fspseva/huitl-cloud)** | Key registry + verification API |
| **[Template: Auth](https://github.com/fspseva/huitl-template-auth)** | Product authentication with ownership |

## Contributing

See [CONTRIBUTING.md](./CONTRIBUTING.md).

## License

MIT