# Identity-Linked Token Protocol

Jake Jones (<jake.jones@bsvassociation.org>)

## 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:

```xml
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

```json
{
  "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

```xml
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:

```json
{
  "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

```javascript
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:

```json
{
  "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:

```xml
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

```json
{
  "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)

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

### 2. Geographic Restrictions

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

### 3. Age-Restricted Assets

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

### 4. Institutional Trading

```javascript
// 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

```javascript
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

```javascript
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


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://bsv.brc.dev/tokens/0108.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
