Identity-Linked Token Protocol

Jake Jones ([email protected])

Abstract

This proposal extends the Enhanced Mandala Token Protocol (BRC-107) with identity certificate integration based on BRC-52/53. It enables tokens to enforce real-world compliance requirements, KYC/AML regulations, and identity-based access controls while preserving privacy through selective field revelation. The protocol supports regulated security tokens, accredited investor requirements, geographic restrictions, and identity-based recovery mechanisms, all validated through SPV-friendly cryptographic proofs.

Motivation

Current token systems on BSV lack native integration with identity verification, making regulatory compliance difficult and limiting adoption for security tokens and regulated assets. While BRC-52/53 provides a robust identity certificate system, there's no standard for linking these certificates to token ownership and transfers.

This proposal addresses:

  • Regulatory compliance for security tokens requiring KYC/AML

  • Accredited investor verification for restricted offerings

  • Geographic restrictions for regulatory jurisdictions

  • Identity-based recovery for lost keys

  • Privacy-preserving compliance through selective revelation

  • Fraud prevention through identity linkage

Specification

Identity-Bound Token Types

We define three levels of identity requirements for tokens:

  1. Open Tokens: No identity requirements (backward compatible with BRC-92/BRC-107)

  2. Verified Tokens: Require valid BRC-52 certificate

  3. Restricted Tokens: Require specific certificate fields or types

Enhanced Genesis Output

The genesis transaction establishes identity requirements:

21 <assetId>
<issuerCertificateHash>
<complianceRules>
<identityCommitment>
OP_2DROP OP_2DROP OP_2DROP OP_DROP ...

Where:

  • issuerCertificateHash: SHA-256 hash of issuer's BRC-52 certificate

  • complianceRules: Encoded rules for token transfers

  • identityCommitment: H(assetId || issuerCertificate || complianceRules || maxSupply)

Compliance Rules Structure

{
  "version": 1,
  "requireIdentity": true,
  "allowedCertificateTypes": [
    "8l5phhdm2Hi80s6QqFOLS0NwUzDzJhlUTWv2BezmstE="
  ],
  "requiredFields": ["country", "accreditedStatus"],
  "restrictions": {
    "allowedCountries": ["US", "CA", "GB"],
    "minCertificateLevel": "enhanced_kyc",
    "maxAmountPerIdentity": 10000,
    "cooldownPeriod": 86400
  }
}

Identity-Linked Token Output

21 <assetId> <amount>
<recipientCertificateHash>
<identityCommitment>
OP_2DROP OP_2DROP OP_2DROP OP_DROP P2PKH

Where:

  • recipientCertificateHash: SHA-256 hash of recipient's BRC-52 certificate

  • identityCommitment: H(assetId || amount || certificateHash || prevTxid)

Identity-Aware Transfer Protocol

When transferring identity-linked tokens, the sender provides:

{
  "transaction": "hex_encoded_transaction",
  "tokenProofs": {
    "inputs": [...],
    "outputs": [...],
    "conservationProof": {...}
  },
  "identityProofs": {
    "sender": {
      "certificate": {
        "type": "8l5phhdm2Hi80s6QqFOLS0NwUzDzJhlUTWv2BezmstE=",
        "subject": "0376d67c86b45be3c36c328c2aa5c5dd79c546d2...",
        "serialNumber": "kUahacBHmYL2nkzemkatFg==",
        "certifier": "035ce8cc44dbcf4c991d666d381d67263aed9123...",
        "revocationOutpoint": "48645047cd66f7b48b24efb080ec7e27...1",
        "signature": "3045022100c0686907...",
        "keyring": {
          "country": "encrypted_for_recipient",
          "accreditedStatus": "encrypted_for_recipient"
        }
      },
      "certificateProof": {
        "merkleProof": "...",
        "blockHeight": 850000
      }
    },
    "recipient": {
      "certificateHash": "sha256_hash_of_recipient_certificate",
      "certificateType": "8l5phhdm2Hi80s6QqFOLS0NwUzDzJhlUTWv2BezmstE="
    }
  },
  "complianceAttestation": {
    "rulesVersion": 1,
    "checksPassed": [
      "country_allowed",
      "accredited_investor",
      "amount_within_limit"
    ],
    "timestamp": 1234567890,
    "attestorSignature": "..."
  }
}

Verification Protocol

Recipients and overlays MUST verify:

1. Standard Token Checks (from BRC-106)

  • Commitment verification

  • Conservation check

  • Merkle proof validation

2. Identity Checks

function verifyIdentityCompliance(transfer) {
  // Verify sender's certificate
  if (!verifyCertificate(transfer.identityProofs.sender.certificate)) {
    return false;
  }

  // Check certificate not revoked
  if (isSpent(transfer.identityProofs.sender.certificate.revocationOutpoint)) {
    return false;
  }

  // Verify certificate matches output
  senderCertHash = H(transfer.identityProofs.sender.certificate);
  if (senderCertHash != transfer.transaction.inputs[0].certificateHash) {
    return false;
  }

  // Decrypt and verify required fields
  fields = decryptFields(transfer.identityProofs.sender.certificate.keyring);
  if (!meetsComplianceRules(fields, token.complianceRules)) {
    return false;
  }

  // Verify recipient certificate type
  if (!token.complianceRules.allowedCertificateTypes.includes(
    transfer.identityProofs.recipient.certificateType)) {
    return false;
  }

  return true;
}

Selective Field Revelation

Certificate holders reveal only required fields:

  1. Determine Required Fields: Based on token's compliance rules

  2. Encrypt for Recipient: Using BRC-52/53 key derivation

  3. Include in Transfer: Add encrypted keys to certificate keyring

  4. Recipient Decrypts: Using their identity key

Example revealing only country for geographic restriction:

{
  "certificate": {
    "fields": {
      "firstName": "encrypted_not_revealed",
      "lastName": "encrypted_not_revealed",
      "country": "encrypted_value",
      "city": "encrypted_not_revealed"
    },
    "keyring": {
      "country": "encrypted_revelation_key_for_recipient"
    }
  }
}

Identity-Based Recovery

Tokens can include recovery conditions:

21 <assetId> <amount>
<primaryCertificateHash>
<recoveryCommitment>
OP_IF
  <recoveryDelay> OP_CHECKSEQUENCEVERIFY OP_DROP
  <recoveryCertificateHash> OP_EQUAL
OP_ELSE
  <primaryCertificateHash> OP_EQUAL
OP_ENDIF

Where:

  • recoveryCommitment: H(certificateType || recoveryFields || recoveryPubkey)

  • recoveryDelay: Time lock before recovery (e.g., 30 days)

Certificate Levels and Permissions

{
  "certificateLevels": {
    "basic_kyc": {
      "maxTransferAmount": 1000,
      "dailyLimit": 5000,
      "allowedOperations": ["transfer", "receive"]
    },
    "enhanced_kyc": {
      "maxTransferAmount": 10000,
      "dailyLimit": 50000,
      "allowedOperations": ["transfer", "receive", "stake"]
    },
    "institutional": {
      "maxTransferAmount": null,
      "dailyLimit": null,
      "allowedOperations": ["transfer", "receive", "stake", "mint", "burn"]
    }
  }
}

Use Cases

1. Security Token Offering (STO)

// Genesis specifies accredited investor requirement
complianceRules = {
  requiredFields: ["accreditedStatus", "country"],
  allowedCountries: ["US"],
  restrictions: {
    mustBeAccredited: true,
    minInvestment: 10000
  }
}

2. Geographic Restrictions

// Token only transferable within specific regions
complianceRules = {
  requiredFields: ["country"],
  allowedCountries: ["EU", "UK", "CH"],
  restrictions: {
    blockRestrictedCountries: ["US", "CN", "RU"]
  }
}

3. Age-Restricted Assets

// Gaming tokens requiring age verification
complianceRules = {
  requiredFields: ["ageRange"],
  restrictions: {
    minimumAge: 18,
    requireAgeAttestation: true
  }
}

4. Institutional Trading

// Different limits based on certificate type
if (certificate.type == "retail") {
  maxDailyVolume = 10000;
} else if (certificate.type == "qualified") {
  maxDailyVolume = 100000;
} else if (certificate.type == "institutional") {
  maxDailyVolume = unlimited;
}

Privacy Considerations

Zero-Knowledge Proofs

For sensitive compliance checks, support ZK proofs:

  • Prove age > 18 without revealing exact age

  • Prove accredited status without revealing net worth

  • Prove country membership without revealing specific country

Encrypted Field Storage

All certificate fields remain encrypted until revelation:

  • Only revealed fields are decrypted

  • Revelation is counterparty-specific

  • No permanent plaintext exposure

Pseudonymous Compliance

Users can maintain pseudonymity while proving compliance:

  • Certificate links to pubkey, not real name

  • Only certifier knows real identity

  • Selective revelation preserves privacy

Security Considerations

Certificate Validation

  • Always verify certificate signatures

  • Check revocation status via UTXO

  • Validate certifier is trusted

  • Ensure certificate hasn't expired

Replay Protection

  • Include prevTxid in commitments

  • Timestamp compliance attestations

  • Use nonces for uniqueness

Key Compromise

  • Certificate revocation via UTXO spending

  • Recovery mechanisms for token access

  • Time-locked recovery periods

Migration and Compatibility

Backward Compatibility

  • Open tokens work without identity

  • Existing BRC-92/106 tokens unaffected

  • Optional identity for gradual adoption

Migration Path

  1. Phase 1: Deploy identity-aware wallets

  2. Phase 2: Certifiers issue BRC-52 certificates

  3. Phase 3: Token issuers adopt compliance rules

  4. Phase 4: Overlays enforce identity requirements

  5. Phase 5: Full ecosystem adoption

Implementation Examples

Creating Identity-Linked Token

async function createIdentityToken(params) {
  // Get issuer's certificate
  const issuerCert = await wallet.getCertificate();

  // Define compliance rules
  const rules = {
    requireIdentity: true,
    allowedCertificateTypes: [params.certificateTypeId],
    requiredFields: params.requiredFields,
    restrictions: params.restrictions
  };

  // Create genesis with identity binding
  const genesis = {
    assetId: generateAssetId(),
    issuerCertificateHash: hash(issuerCert),
    complianceRules: rules,
    identityCommitment: hash(
      assetId + issuerCert + rules + params.maxSupply
    )
  };

  return createGenesisTransaction(genesis);
}

Transferring with Compliance

async function transferWithCompliance(amount, recipient) {
  // Get certificates
  const senderCert = await wallet.getCertificate();
  const recipientCert = await requestCertificate(recipient);

  // Check compliance
  const compliance = await checkCompliance(
    senderCert,
    recipientCert,
    token.complianceRules
  );

  if (!compliance.passed) {
    throw new Error(`Compliance failed: ${compliance.reason}`);
  }

  // Reveal required fields
  const keyring = await revealFields(
    senderCert,
    token.complianceRules.requiredFields,
    recipient
  );

  // Create transfer
  return {
    transaction: createTokenTransfer(amount, recipient),
    identityProofs: {
      sender: {
        certificate: senderCert,
        keyring: keyring
      },
      recipient: {
        certificateHash: hash(recipientCert)
      }
    },
    complianceAttestation: compliance.attestation
  };
}

Test Vectors

Identity Commitment

Input:
  assetId: "abc...def:0"
  certificateHash: "123...789"
  amount: 100
  prevTxid: "def...456"

Output:
  commitment = SHA256(assetId || amount || certificateHash || prevTxid)
             = "xyz...123"

Compliance Check

Certificate Fields:
  country: "US"
  accreditedStatus: "true"

Compliance Rules:
  allowedCountries: ["US", "CA"]
  mustBeAccredited: true

Result: PASS ✓

References

  • BRC-52: Identity Certificates

  • BRC-53: Certificate Creation and Revelation

  • BRC-92: Mandala Token Protocol

  • BRC-107: Enhanced Mandala Token Protocol

  • BRC-43: Security Levels, Protocol IDs, Key IDs and Counterparties

  • BRC-2: Data Encryption and Decryption

  • BRC-3: Digital Signature Creation and Verification

Implementations

Reference implementations:

  • TypeScript: Coming Soon

  • Go: Coming Soon

  • Python: Coming Soon

Last updated

Was this helpful?