← Blocktrails Profiles

Git-mark Profile (v0.1)

Git commits anchored to Bitcoin via Blocktrails output-key commitments.

Abstract

Git-mark binds Bitcoin UTXOs to Git commits using elliptic curve tweaking. Each commit hash becomes a scalar tweak that derives a new pubkey, creating a cryptographic chain linking repository history to Bitcoin.

1. Introduction

Git-mark creates a two-way binding between Git and Bitcoin:

Unlike Monochrome profiles which use JCS-serialized state as the tweak source, git-mark uses Git commit hashes directly.

2. Cryptographic Model

2.1 Chained Key Derivation

Git-mark follows the Blocktrails chained derivation model:

Genesis: P₀ = d₀ × G (base pubkey) Commit 1: P₁ = P₀ + scalar(commit₁) × G (tweaked by first commit) Commit 2: P₂ = P₁ + scalar(commit₂) × G (tweaked by second commit) ... Commit n: Pₙ = Pₙ₋₁ + scalar(commitₙ) × G

2.2 Scalar Function

For git-mark, the scalar is the git commit hash interpreted as a big-endian integer:

scalar(commit) := int(commit_hash, big-endian) mod n

Where commit_hash is the 20-byte (40 hex character) git commit hash, and n is the secp256k1 curve order.

Since git uses SHA-1, the commit hash is already a cryptographic hash. No additional hashing is needed.

If scalar(commit) = 0, the commit MUST be rejected (probability ~2-160).

2.3 Private Key Derivation

The spending key for any state:

d_n = d₀ + scalar(commit₁) + scalar(commit₂) + ... + scalar(commitₙ)  (mod n)

3. TXO URI Format

Git-mark uses TXO URIs to record the on-chain state:

txo:<network>:<txid>:<vout>?amount=<sats>&pubkey=<hex>[&commit=<git_hash>]
FieldTypeDescription
networkstringBitcoin network (mainnet, tbtc4, signet)
txidhex64Transaction ID (64 hex characters)
voutintegerOutput index
amountintegerValue in satoshis
pubkeyhex64X-only pubkey (64 hex characters)
commithex40Git commit hash (absent for genesis)

3.1 Genesis TXO

The genesis TXO has no commit parameter. Its pubkey is the base pubkey P₀:

txo:tbtc4:34cea31b...e854be0e:0?amount=1000000&pubkey=3e458cc6...a5c8cf

3.2 Subsequent TXOs

Each subsequent TXO includes the commit that tweaked to this pubkey:

txo:tbtc4:45fbcbd7...81a9f7d:0?amount=999000&pubkey=b5bc388c...5266c&commit=cf97baba...83d17d

4. State Transitions

4.1 Transition Flow

┌─────────────┐ │ Git Commit │ │ (state Δ) │ └──────┬──────┘ │ hash ▼ ┌──────────┐ tweak ┌──────────┐ │ P_old │────────────→│ P_new │ │ (UTXO₁) │ │ (UTXO₂) │ └──────────┘ └──────────┘ │ │ │ spend │ new output ▼ ▼ ┌────────────────────────────────────┐ │ Bitcoin Transaction │ └────────────────────────────────────┘

4.2 Making a Transition

  1. Create git commit with state changes
  2. Compute new pubkey: P_new = P_current + scalar(commit) × G
  3. Spend current UTXO to new pubkey
  4. Append new TXO URI to txo.json
  5. Push to git remote

5. Directory Structure

Git-mark state is stored in the repository:

.well-known/
└── txo/
    └── txo.json      # Array of TXO URIs

5.1 txo.json Format

Simple JSON array of TXO URI strings:

[
  "txo:tbtc4:<txid>:0?amount=1000000&pubkey=<genesis_pubkey>",
  "txo:tbtc4:<txid>:0?amount=999000&pubkey=<pubkey>&commit=<hash>",
  "txo:tbtc4:<txid>:0?amount=998000&pubkey=<pubkey>&commit=<hash>"
]

6. Verification

6.1 Chain Validity

A git-mark chain is valid if:

  1. Genesis: First TXO has no commit, pubkey is valid point
  2. Continuity: Each subsequent pubkey = prev_pubkey + scalar(commit) × G
  3. On-chain: Each UTXO exists (or existed) on Bitcoin
  4. Git validity: Commit hashes correspond to actual git commits

6.2 Verification Algorithm

function verify(txoUris):
  txos = parse(txoUris)

  // Genesis check
  if txos[0].commit != null:
    return { valid: false, error: "genesis has commit" }

  // Try both Y parities (x-only loses parity)
  for prefix in [0x02, 0x03]:
    basePubkey = prefix || txos[0].pubkey

    commits = []
    valid = true
    for i = 1 to txos.length - 1:
      commits.push(txos[i].commit)
      expected = deriveChainedPubkey(basePubkey, commits)
      if xonly(expected) != txos[i].pubkey:
        valid = false
        break

    if valid:
      return { valid: true }

  return { valid: false, error: "pubkey mismatch" }

6.3 Commit Selection and Ordering

Commits anchored to the TXO chain need not be consecutive in git history. Any commit may be selected for marking. However:

The EC_ADD verification ensures pubkey chain integrity. Git ancestry verification is an additional check that confirms the logical ordering of state transitions.

7. Comparison with Monochrome

AspectGit-markMonochrome
Tweak sourceGit commit hashsha256(JCS(state))
State storageGit tree objectsJSON state array
State formatAny git contentStructured JSON with ops
LinkingTXO URI in txo.jsonState contains prev hash
Use caseRepository anchoringApplication state machines

Git-mark leverages Git's existing content-addressed storage and commit graph. Monochrome defines its own state schema with explicit operations.

8. Security Considerations

8.1 Inherited from Blocktrails

8.2 Git-mark Specific

ThreatMitigation
Commit rewritingGit's content-addressing; verifiers check commit exists
History divergenceTXO chain anchors specific commit sequence
UTXO availabilityBitcoin full node or SPV verification
txo.json tamperingVerify pubkey derivation matches recorded commits

8.3 Trust Model

9. Implementation

Reference implementation: blocktrails/git-mark

npm install git-seal

git mark init
git mark genesis --txid <txid> --vout 0 --amount 1000000
git commit -m "state change"
git mark advance --txid <txid> --vout 0 --amount 999000
git mark verify

10. References