Note: This is a client-side playground for DSPIP SHIP (shipping) protocol. All operations run in your browser using JavaScript cryptography libraries. No data is sent to any server. Supports standard, encrypted, and split-key privacy modes.
POST Generate Key Pair

Generate a new secp256k1 key pair for DSPIP signing operations. Returns both private and public keys.

🧪 Try It
Warning: The generated private key is displayed for testing purposes only. In production, never expose private keys.
Response Waiting
{
  "message": "Click 'Run' to generate a new key pair"
}
Code Samples
// Using @noble/secp256k1 for DSPIP shipping
import * as secp from '@noble/secp256k1';

// Generate random private key
const privateKey = secp.utils.randomPrivateKey();

// Derive compressed public key (33 bytes)
const publicKey = secp.getPublicKey(privateKey, true);

// Convert to hex strings
const privateKeyHex = bytesToHex(privateKey);
const publicKeyHex = bytesToHex(publicKey);

// Base64 for DNS TXT record (p= tag)
const publicKeyBase64 = btoa(
  String.fromCharCode(...publicKey)
);

// DNS record format with lifecycle fields:
// v=DSPIP1; k=ec; c=secp256k1; p={base64};
// t={created}; exp={sign_expires}; exp-v={verify_expires};
// s=active; seq=1; types=SHIP
# Using coincurve library
from coincurve import PrivateKey
import base64

# Generate new key pair
private_key = PrivateKey()
public_key = private_key.public_key

# Get hex representations
private_key_hex = private_key.to_hex()
public_key_hex = public_key.format(True).hex()

# Base64 for DNS record
public_key_base64 = base64.b64encode(
    public_key.format(True)
).decode()
// Using go-ethereum/crypto
import (
    "crypto/ecdsa"
    "encoding/base64"
    "encoding/hex"
    "github.com/ethereum/go-ethereum/crypto"
)

// Generate new key pair
privateKey, _ := crypto.GenerateKey()
publicKey := privateKey.PublicKey

// Compress public key
pubBytes := crypto.CompressPubkey(&publicKey)

// Encode
privHex := hex.EncodeToString(
    crypto.FromECDSA(privateKey))
pubBase64 := base64.StdEncoding.EncodeToString(
    pubBytes)
# Key generation is done client-side
# For testing, use OpenSSL:

# Generate private key
openssl ecparam -name secp256k1 \
  -genkey -noout -out private.pem

# Extract public key
openssl ec -in private.pem \
  -pubout -out public.pem

# Get hex format
openssl ec -in private.pem \
  -text -noout
Response Schema
{
  "privateKey": "string (64 hex chars)",
  "publicKey": {
    "hex": "string (66 hex chars)",
    "base64": "string (44 chars)"
  },
  "ethereumAddress": "string (optional)"
}
POST Derive Public Key

Derive the public key from a private key. Useful for verifying key pairs.

🧪 Try It
Parameters
privateKey * hex string
Response Waiting
{
  "message": "Enter a private key and click 'Run'"
}
POST Create SHIP Payload

Create a DSPIP SHIP payload with issuer/subject structure and privacy mode selection. Encodes to Base64.

🧪 Try It
Required Fields
itemId * string
privacyMode * enum
issuerCountry * ISO 3166-1
Issuer (Sender) Fields
issuerOrg string
issuerCity string
issuerState string
Subject (Recipient) Fields
subjectName string
subjectCity string
lastMileProvider key locator
Shipping Details (typeData)
carrier string
service string
Response Waiting
{
  "message": "Fill in the fields and click 'Run'"
}
POST Sign Payload

Sign a DSPIP payload using ECDSA with SHA-256. Creates a DER-encoded signature.

🧪 Try It
Parameters
privateKey * hex string
keyLocator * string
encodedPayload * base64
Response Waiting
{
  "message": "Enter parameters and click 'Run'"
}
POST Generate QR Data

Generate complete DSPIP SHIP QR code data string with 6-7 pipe-delimited fields: DSPIP|version|type|keyLocator|payload|signature

🧪 Try It
Parameters
version string
keyLocator * string
encodedPayload * base64
signature * hex string
Response Waiting
{
  "message": "Enter parameters and click 'Run'"
}
POST Parse QR Data

Parse a DSPIP QR code string (6-7 pipe-delimited fields) into its components, validate type=SHIP, and decode the payload.

🧪 Try It
Parameters
qrData * string
Response Waiting
{
  "message": "Enter QR data and click 'Run'"
}
POST Verify Signature

Verify an ECDSA signature against a public key and message.

🧪 Try It
Parameters
publicKey * base64
message * string
signature * hex string
Response Waiting
{
  "message": "Enter parameters and click 'Run'"
}
GET DNS Lookup

Look up a DSPIP public key from DNS TXT records using DNS over HTTPS.

🧪 Try It
Parameters
keyLocator * string
Uses Cloudflare DNS over HTTPS (1.1.1.1) for lookups. For the test key locator, a simulated response is returned.
Response Waiting
{
  "message": "Enter key locator and click 'Run'"
}
POST SHA-256 Hash

Calculate the SHA-256 hash of input data. Used internally for signature creation.

🧪 Try It
Parameters
data * string
Response Waiting
{
  "message": "Enter data and click 'Run'"
}
POST Base64 Encode/Decode

Encode or decode data using Base64. Used for payload encoding in DSPIP.

🧪 Try It
Parameters
data * string
Response Waiting
{
  "message": "Enter data and click 'Encode' or 'Decode'"
}
POST ECIES Encrypt

Encrypt data for a recipient using ECIES (Elliptic Curve Integrated Encryption Scheme). Used in privacy modes to encrypt recipient information for Last Mile Providers (Section 4.3).

🧪 Try It
ECIES uses ephemeral key agreement with AES-256-GCM encryption. The recipient's public key is used to derive a shared secret, which encrypts the data. Only the recipient's private key can decrypt.
Parameters
recipientPublicKey * base64
plaintext * string
Response Waiting
{
  "message": "Enter recipient public key and plaintext, then click 'Encrypt'"
}
POST ECIES Decrypt

Decrypt ECIES-encrypted data using the recipient's private key. Used by Last Mile Providers to access encrypted recipient information.

🧪 Try It
Parameters
privateKey * hex string
ciphertext * JSON
Response Waiting
{
  "message": "Enter private key and ciphertext, then click 'Decrypt'"
}
POST Ed25519 Key Pair

Generate an Ed25519 key pair for split-key labels. Ed25519 provides fast signing for physical anti-cloning mechanisms (Section 7.3).

🧪 Try It
Ed25519 is used for split-key labels where the private key is physically protected under a scratch-off layer. Fast verification with 64-byte signatures.
Response Waiting
{
  "message": "Click 'Generate' to create a new Ed25519 key pair"
}
POST Check Revocation

Check if an item ID has been revoked using Bloom filter (Section 5.5). Returns probable revocation status for high-volume checking.

🧪 Try It
Bloom filters provide probabilistic revocation checking with no false negatives. An item may be flagged as "possibly revoked" and require confirmation, but will never miss an actual revocation.
Parameters
itemId * string
Response Waiting
{
  "message": "Enter item ID and click 'Check'"
}
POST Create Delivery Challenge

Create a cryptographic challenge for delivery confirmation (Section 5.6). The recipient must sign this challenge to prove possession of their private key.

🧪 Try It
Delivery confirmation uses a challenge-response protocol. The carrier generates a random nonce, the recipient signs it, proving they received the package without revealing their key.
Parameters
itemId * string
carrierKeyLocator * string
Response Waiting
{
  "message": "Enter parameters and click 'Create Challenge'"
}
GET Lookup Providers

Look up Last Mile Providers by postal code or geographic location (Section 7.2.5). Returns providers that service the specified area.

🧪 Try It
Directory services help senders find appropriate Last Mile Providers for privacy-preserving delivery. Providers publish their coverage areas and can be queried by postal code or coordinates.
Parameters
postalCode string
countryCode ISO 3166-1
Response Waiting
{
  "message": "Enter postal code and click 'Lookup'"
}
POST Parse Address Field

Parse a DSPIP address field from DNS TXT records (Section 5.2.1). Supports Plus Codes, street addresses, geographic coordinates, and facility codes.

🧪 Try It
Address fields support multiple schemes: plus: (Google Plus Codes), street: (traditional addresses), geo: (lat,long coordinates), and facility: (internal codes).
Parameters
addressField * string
Response Waiting
{
  "message": "Enter address field and click 'Parse'"
}