Skip to main content
Research Preview — Under active development.

Location Proofs

Location Proofs provide evidence-based verification of location claims. They answer the question: How confident can we be that a subject was at a claimed location during a claimed time?

Core Concepts

Location Claims

A Location Claim is an assertion about the timing and location of an event. Claims extend the Location Protocol specification:
interface LocationClaim {
  // Location Protocol v0.2 fields
  lpVersion: string;            // "0.2"
  locationType: string;         // "geojson-point", "h3-index", etc.
  location: LocationData;       // The asserted location
  srs: string;                  // Spatial reference system

  // Verification-specific fields
  subject: SubjectIdentifier;   // Who/what was at the location
  radius: number;               // Spatial uncertainty (meters) — required
  time: { start: number; end: number };  // Temporal bounds
  eventType?: string;           // "presence", "transaction", "delivery"
}
radius is required — you cannot claim presence at an exact point. Both spatial and temporal bounds involve uncertainty.
The event could be: a person’s presence, a transaction’s origin, an asset’s location, a delivery, etc.

Location Stamps

A Location Stamp is evidence from a proof-of-location system. Stamps are independent of claims — they provide evidence about an observed location, which may come from:
  • Direct observation: Hardware attestation, network measurements
  • Indirect/derived sources: Documents, records, institutional attestations
interface LocationStamp {
  // Location data (LP v0.2) — the OBSERVED location
  lpVersion: string;
  locationType: string;
  location: LocationData;       // Where evidence indicates subject was
  srs: string;

  // Temporal footprint
  temporalFootprint: { start: number; end: number };

  // Plugin identification
  plugin: string;               // "proofmode" | "witnesschain"
  pluginVersion: string;

  // Evidence and signatures
  signals: Record<string, unknown>;
  signatures: Signature[];
}
Both claims and stamps use Location Protocol format for their location data:
  • Claim location = asserted location (where subject claims to have been)
  • Stamp location = observed location (where evidence indicates subject was)
Verification compares: does the observed support the asserted?

Location Proofs

A Location Proof bundles stamps with a claim — this is the verifiable artifact:
interface LocationProof {
  claim: LocationClaim;
  stamps: LocationStamp[];   // One or more stamps
}
Single-stamp proofs are valid. Multi-stamp proofs from independent systems enable cross-correlation analysis.

Verification

Verification (Evidence Evaluation) is a three-phase process:
  1. Verify each stamp — Check signatures, structure, signal consistency
  2. Assess stamps against claim — Does the observed location support the asserted location?
  3. Assess cross-correlation — Do multiple stamps corroborate each other?
The output is a Credibility Assessment.

Credibility Assessment

Verification outputs a structured assessment, not just a yes/no:
interface CredibilityAssessment {
  confidence: number;           // 0-1 overall score
  stampResults: StampResult[];  // Per-stamp verification
  correlation?: {               // For multi-stamp proofs
    independence: number;       // Are sources uncorrelated?
    agreement: number;          // Do sources agree?
  };
}
Confidence ≠ Probability. A confidence of 0.8 does NOT mean “80% probability the claim is true.” It means “the evidence is reasonably strong.” Calibrating to true probability is future work.

Multi-Factor Proofs

Multiple stamps from independent systems increase confidence:
// Single stamp: moderate confidence
const result1 = await astral.verify.proof({
  claim,
  stamps: [proofmodeStamp]
});
// result1.credibility.confidence → 0.7

// Multi-stamp from independent systems: higher confidence
const result2 = await astral.verify.proof({
  claim,
  stamps: [proofmodeStamp, witnessStamp]
});
// result2.credibility.confidence → 0.9
// result2.credibility.correlation.independence → 0.95
Key principle: Independent, corroborating evidence increases confidence. Redundant stamps from the same system don’t add confidence — but they don’t subtract either.

Plugins

Stamps come from a range of plugins — an extensible library of proof-of-location systems:

ProofMode

Device attestation + sensor fusion
  • iOS (Swift, Secure Enclave)
  • Android (Kotlin, hardware keystore)
  • React Native wrapper
  • Trust: Device integrity

WitnessChain

Infrastructure verification
  • Node.js server
  • UDP latency triangulation
  • Challenger network
  • Trust: Speed of light + cryptoeconomic
Each plugin documents its own threat model and trust assumptions.

The Uncertainty Tradeoff

Location proofs involve uncertainty in both space and time: Larger bounds = Higher confidence, Lower precision
  • “Somewhere in California during 2024” — easy to verify, not very useful
  • “Within 10m at 14:32:07” — precise, but hard to verify confidently
Applications decide what precision/confidence balance they need. Broader claims may be valuable for privacy preservation.

Forgery Resistance

The cost of forging a location proof should exceed the economic value of the transaction it underpins.
This is application-specific:
  • $10 check-in reward → lower forgery resistance needed
  • $10M land title transfer → higher forgery resistance needed
The credibility assessment helps applications make this determination.

SDK Usage

Code snippets need testing — Verify against actual implementation before use.

Collecting Evidence

import { AstralSDK } from '@decentralized-geo/astral-sdk';

// Configure plugin
const pluginOptions = {
  name: 'proofmode',
  version: '0.1.0',
  config: { timeout: 5000 }
};

// Collect signals
const signals = await astral.stamps.collect(pluginOptions);

// Create and sign stamp
const unsigned = await astral.stamps.create(pluginOptions, signals);
const stamp = await astral.stamps.sign(unsigned, deviceSigner);

Creating and Verifying a Proof

// Define claim (extends Location Protocol)
const claim = {
  lpVersion: '0.2',
  locationType: 'geojson-point',
  location: { type: 'Point', coordinates: [-122.4194, 37.7749] },
  srs: 'http://www.opengis.net/def/crs/OGC/1.3/CRS84',
  subject: { scheme: 'eth-address', value: '0x...' },
  radius: 100,  // meters — required
  time: { start: Date.now() / 1000 - 60, end: Date.now() / 1000 },
  eventType: 'presence'
};

// Bundle into proof
const proof = astral.proofs.create(claim, [stamp]);

// Verify
const result = await astral.verify.proof(proof);

console.log(result.credibility.confidence);  // 0.85
console.log(result.uid);                     // 0xabc123...

Output: Verified Location Proof

The final output is an EAS attestation:
interface VerifiedLocationProof {
  proof: LocationProof;
  credibility: CredibilityAssessment;
  uid: string;
  attester: string;        // Astral service address
  timestamp: number;
  chainId?: number;        // If submitted onchain
}
Can be onchain or offchain — no requirement to submit onchain.

Relationship to Geospatial Operations

Location Verification is upstream of Geospatial Operations:
Location VerificationGeospatial Operations
Evaluates evidence credibilityComputes spatial relationships
Input: location proof (claim + stamps)Input: locations (claimed or verified)
Output: credibility assessmentOutput: policy attestation
”How confident are we that X was at L?""Is A inside B?”
Verified location proofs can serve as trusted inputs to geospatial operations, increasing confidence in computed results.

Integration with Compute

Verified Location Proofs can be used as inputs to Geospatial Operations:
// Verify user's location
const verifiedProof = await astral.verify.proof(proof);

// Use as trusted input to geospatial operation
const result = await astral.compute.contains({
  container: sfBayAreaPolygonUID,
  geometry: { verifiedProof: verifiedProof.uid },
  chainId: 84532,
  schema: SCHEMA_UID
});

Next: Geospatial Operations

Learn about spatial computations on location data