Skip to main content

Core Concepts

Understand the fundamental concepts behind L{CORE}.


The Oracle Problem

Blockchains are deterministic - given the same inputs, every node produces the same output. This is essential for consensus, but it creates a challenge: blockchains can't natively access external data.

Traditional solutions use "oracles" - trusted third parties that feed data to smart contracts. But this introduces trust assumptions that undermine blockchain's trustless nature.

L{CORE} solves this differently: instead of trusting an oracle's word, we cryptographically prove that data came from a specific source at a specific time.


Attestation vs. Oracles

AspectTraditional OracleL{CORE} Attestation
Trust modelTrust the oracle operatorTrust cryptographic proof
Data sourceOracle fetches and reportsProve data came from source
Verification"Oracle says X""Source said X, here's proof"
PrivacyOracle sees all dataData can be bucketed/encrypted
CentralizationSingle point of failureVerifiable by anyone

How Attestation Works

1. zkTLS Proof

When you request an attestation, the Attestor:

  1. Establishes a TLS connection to the data source
  2. Records the cryptographic handshake
  3. Generates a zero-knowledge proof that:
    • The connection was to the claimed server
    • The response matches what was received
    • The timestamp is accurate

This proof is verifiable by anyone without re-fetching the data.

2. Privacy Processing

Before storing, data goes through privacy processing:

  • Bucketing: Convert income: $75,432 to income: 50k-100k
  • Encryption: Encrypt sensitive fields with NaCl box
  • Redaction: Remove fields that shouldn't be stored

3. Deterministic Storage

The processed claim is submitted to Cartesi, which:

  • Validates the attestation proof
  • Stores data in SQLite
  • Produces a notice (on-chain record)

Privacy Buckets

Privacy buckets are L{CORE}'s core privacy primitive. They convert continuous values into categorical ranges.

Why Buckets?

Smart contracts often need to answer questions like:

  • "Is this user's income above $50k?"
  • "Is the temperature in the safe range?"
  • "Is the account balance sufficient?"

They don't need exact values - just ranges. Buckets provide exactly this.

Bucket Definition

{
field: 'income',
boundaries: [0, 25000, 50000, 100000, 250000],
labels: ['<25k', '25k-50k', '50k-100k', '100k-250k', '>250k']
}

Given income: $75,432:

  • Falls between 50000 and 100000
  • Assigned label: '50k-100k'
  • Original value never stored

Bucket Properties

  1. Irreversible: Can't recover exact value from bucket
  2. Consistent: Same value always maps to same bucket
  3. Configurable: Define boundaries per use case
  4. Verifiable: Proof includes bucket assignment

The Two-Layer Architecture

L{CORE} separates concerns into two layers:

Attestor Layer

The Attestor handles:

  • External network requests
  • zkTLS proof generation
  • Privacy processing
  • Blockchain transactions

It's non-deterministic - it interacts with the outside world.

Cartesi Layer

The Cartesi rollup handles:

  • Data validation
  • SQLite storage
  • Query processing
  • State management

It's deterministic - same inputs always produce same outputs.

Why Separation?

Cartesi rollups must be deterministic for verification. If the Cartesi code made network calls, different validators could get different responses, breaking consensus.

By separating layers:

  • Attestor does the non-deterministic work (fetching, proving)
  • Cartesi does deterministic work (validating, storing)
  • The proof bridges the gap

Claims and Attestations

Claim

A claim is a statement about data:

  • "User X has income in range Y"
  • "Sensor Z reported temperature T at time S"
  • "API returned response R"

Attestation

An attestation is a claim + cryptographic proof:

  • The claim itself
  • zkTLS proof of data source
  • Timestamp
  • Attestor signature

Claim Lifecycle

1. Request     -> SDK calls attestor
2. Fetch -> Attestor fetches data
3. Prove -> zkTLS proof generated
4. Process -> Privacy buckets applied
5. Submit -> Transaction to InputBox
6. Store -> Cartesi stores in SQLite
7. Query -> Data available via inspect

Encryption

For data that can't be bucketed, L{CORE} provides encryption.

NaCl Box Encryption

L{CORE} uses NaCl box (Curve25519 + XSalsa20-Poly1305):

  • Asymmetric encryption
  • Only the key holder can decrypt
  • Data stored encrypted in Cartesi

Use Cases

  • SSN, passport numbers (can't bucket meaningfully)
  • Medical records
  • Any PII that needs full privacy

Key Management

// Generate keypair
const keypair = nacl.box.keyPair()
const publicKey = Buffer.from(keypair.publicKey).toString('base64')
const privateKey = Buffer.from(keypair.secretKey).toString('base64')

// Attest with encryption
const claim = await lcore.attest({
provider: 'http',
params: {
url: 'https://api.example.com/sensitive',
encrypt: true,
encryptionKey: publicKey
}
})

// Decrypt later
const decrypted = lcore.decrypt(claim.encryptedData, privateKey)

Providers

Providers define how to fetch and process different data types.

HTTP Provider

The most common provider - attests any HTTP endpoint:

await lcore.attest({
provider: 'http',
params: {
url: 'https://api.example.com/data',
method: 'GET',
headers: { 'Authorization': 'Bearer token' }
}
})

IoT Provider

For IoT devices with platform-specific authentication:

await lcore.attest({
provider: 'iot',
params: {
platform: 'aws-iot',
deviceId: 'sensor-001',
topic: 'sensors/temperature'
}
})

Custom Providers

Define your own provider logic for specialized sources.


Querying Data

Inspect Endpoint

Read data without blockchain transactions:

const result = await lcore.query({
type: 'attestation',
params: { claimId: 'abc123' }
})

This is:

  • Free (no gas costs)
  • Fast (direct HTTP)
  • Read-only

Query Types

TypeDescription
attestationGet specific claim by ID
attestations_by_userAll claims for a user
attestations_by_providerAll claims from a provider
provider_schemasAvailable bucket definitions

Next Steps