Skip to content
bcpki edited this page Feb 8, 2013 · 13 revisions

Technical Desription

BcValues

A bcvalue (blockchain value) is an integer up to 32 bytes in length that we want to get into the blockchain. Common bcvalues are hash digests of documents that we want to sign (e.g. the data part of a certificate) or hash digests of alias names. What is stored in the blockchain is not the bcvalue itself but a pubkey derived from it. To this end, the bcvalue is simply interpreted as a secret (i.e. privkey) and it's corresponding pubkey is then placed in the blockchain instead. Consequently, one can search the blockchain for a given bcvalue, but not conversely, i.e. one cannot tell the bcvalues from just looking at the pubkeys appearing in the blockchain. To summarize, with every bcvalue we have associated:

bcvlaue <-> privkey -> pubkey -> id <-> addr

where -> means one-way derivation. The <-> arrows are base58-check de- and encoding. pubkey is bcvalue*G where G is the base point of the curve. id is the Hash160 of pubkey. We can let bitcoind show us these values with RPC aliasdump:

@onlinemachine: ./bitcoind -testnet aliasdump 3119fff8f75b59d6600511dd3f49fd007d380a87
{
    "bcvalue" : "3119fff8f75b59d6600511dd3f49fd007d380a87",
    "privkey" : "cMahea7zqjxrtgAbB8Gmq4xrmZVdgaZAn4nMAgZoU6swHdDXHrFM",
    "pubkey" : "02bcc1e9deffae03c128eb5e8aaa41f9315aa53074fd04020a46f036c4e68fbdfc",
    "id" : "61d8a13b13e2a81b4e00fc795d373ab9d10dd303",
    "addr" : "mpSKMN6P58TjgkpHqqXfgMVTfFsbpe9oEr"
}

For reverse lookups from the blockchain one needs a server who stores bcvalues indexed by their pubkeys.

Appearance in the blockchain

To place bcvalue in the blockchain we create an explicit (i.e. non-P2SH) MULTISIG output, where the first pubkey is bcvalue's pubkey and the other pubkey(s) protect the output from being spent. We say a given outpoint is an appearance of bcvalue if it meets the following criteria:

  • sigPubKey is an explicit n-to-redeem multisig with n>=2
  • amount is >= some system-wide constant
  • the first pubkey is the one derived from bcvalue

Note that all appearances are part of the UTXO set. The other pubkey(s) from the multisig are called the owners of the appearance.

Aliases and normalization

An alias is a string with similar restrictions as a domain node name: it contains only ASCII letters, digits, _ and -, begins with a letter, does not end with _ or -, and is not empty. However, it can be arbitrary length.

Purpose of aliases

The purpose of an alias is to use it as an ID for people or other entities, so we assume an alias will be used like this:

  • remembered in people's brain
  • passed on orally (e.g. phone, street)
  • passed on written (e.g. email, chat, dashboards)

The first two uses demand that a few things should not matter in an alias:

  • separation with _ or - (foobar should be considered equal to foo_bar)
  • case (foobar should be equal to FooBar)

The second use is facilitated somewhat by:

  • considering repeated characters as single characters (e.g. nn=n)

The third use demands that similar looking characters should be considered equal:

  • 1 = l = I
  • O = 0
Normalization Algorithm

We therefore normalize an alias with the following algorithm:

  1. remove all _ and -
  2. turn to uppercase
  3. replace O by 0
  4. replace I,L by 1
  5. replace repetition by single characters

Example: foo_bar normalizes to F0BAR

Note that normalization does not create resistence against mistyping. A checksum such as mod 97 can be used for that.

BcValue of an alias

The bcvalue associated with an alias is the Hash160 of its normaliation. We can let bitcoind show us these values with RPC aliasdump:

@onlinemachine: ./bitcoind -testnet aliasdump foo1
{
    "normalized" : "BCSIG_v0.4_F01",
    "bcvalue" : "d378cf5f150d277d9412e8dfbc07390b6e10e157",
    "privkey" : "cMahea7zqjxrtgAbB7woC6zafPmx9oc6AMHmJWV6fgFv1FjRE4rw",
    "pubkey" : "024bdb3d9ac1d83afd118281d4b99364a15c4edd8c6f960b84df072b3718a7985a",
    "id" : "418dbc6c2567baab3db74dbdb95bacc7f88e02e2",
    "addr" : "mmVa1WocrVoePpz7HBgsLTiveBD3P81RXf"
}

Since the pubkey will end up in the blockchain, and to not clutter the namespace forever, the normalization is prepended with a version number.

Blockchain Signatures

To sign a bcvalue with alias we place both bcvalues (the one to be signed and the one derived from alias) as two outputs of the same transaction. Since everybody can do that (no secrets are involved) only the first transaction that contains the pubkey derived from alias counts.

Verification of a signature of bcvalue by alias follows this algorithm:

  1. look for the first (oldest) unspent appearence of (the bcvalue of) alias
  • if no appearance exists, signature is invalid
  • if an appearance exists, take its txid
  1. look for an appearance of bcvalue inside the transaction txid
  • if it exists, signature is valid, otherwise invalid

By adding more outputs to the transaction, a single alias can sign more than one bcvalue. Each alias, at each point in time, can only have one valid signing transaction. Signatures of individual bcvalues can be revoked by spending the corresponding outpoint. All signatures of alias can be revoked by spending the outpoint corresponding to the bcvalue of alias.

Note that in the process of signing and revoking:

  • no coins are ever burnt
  • no dust is created
  • all scripts are standard
  • all pubkeys are valid points on the curve
  • no information is encoded in the amount-values

Note that in the process of verifying signatures:

  • only the UTXO set is required

Endian-ness

bcpki interprets hashes and ticket numbers as big-endian numbers.

Big-endian structures are:

  • OpenSSL's BIGNUM
  • CBigNum (wrapper around BIGNUM)
  • CSecret

Little-endian structures are:

  • uint160
  • uint256

Conversions that obey (i.e. change) endian-ness:

  • CBigNum::setuint256/getuint256
  • CBigNum(uint256) constructor
  • CBigNum::setvch/getvch (serialization)

Conversions that maintain big-endian-ness:

  • CBigNum::SetHex/GetHex
  • CBigNum::ToString

Attacks

Homograph attacks

Many are avoided by normalization. Others may require an extended normalization (rn=m?).

Typosquatting

Normalization limits typosquatting, e.g. to swapped adjacent characters. Can only be avoided by introducing checksums, e.g the 2-digit mod 97.

Registration squatting

Incentives for squatting aliases are:

  • resell them
  • make the whole system unusable

One counter-measure is the minimum amount required for an outpoint to be valid. It is currently set to 100 times the transaction fee (i.e. 0.05 BTC). The rationale is that signatures are used for certificates, which are used for the payment protocol, and that someone who wants to receive payments would be willing to put aside 100 transaction fees while running his business (probably even 1000). To squat 100,000 aliases would require to block 5,000 BTC, would effectively loose 100 BTC in fees (unless done by a miner), and would occupy at least (how many?) blocks.

Possible counter measures against reselling:

  • change the system and make signatures unrevokable, i.e verify against all outpoints instead of just the UTXO set