Update 22nd July, 2021

No, I feel we should not (keep the re-issue, so here I agree with your conclusion) and for bad elders that do we might have a slight worry, but I don’t think so. For single use keys, we only need to write a Key Revocation Packet. Lots of internal discussions on this but I an very very keen we have revocation and use a form of it as SpentBook.

Here’s a snippet

Key revocation

Is a mechanism to identify no longer usable keys. The existence of a key in a revocation scheme means the key is no longer trusted and we should not accept any signature from it. In Safe parlance, it carries zero Authority .

Key recycling

Is a mechanism that effectively revokes a key and replaces that key with a new key. In Safe parlance, this means to carry over the Authority .

Key types on Safe

We have

  1. Data keys (a BLS key that Authorises mutations to the Data network).
  2. Node key (an ED25519 key that identifies a node)
  3. DBC key (a BLS key that represents a Dbc “owner”)

Each has differing revocation requirements and we will explain these next.

Detail

Data key revocation

These are always only revoked by the “owner” of the data. However, the choice is to revoke or rotate . Rotation allows the owner to move to another person or simply a new key, in case of possible security issues and users wishing to update keys, i.e. we can carry over the Authority . Revocation means this key can no longer authorise mutations.

Note: This key can be that one given to apps to mutate data and revoking this effectively kills the app for that user.

key == BLSPubKeyName + tag(01) // XorUrl
content ==
enum { Revoke: Signature // of key,
       Rotate: NewBLSPubKey, Signature // of key + new key, 
     }

The Signature in both cases is produced by the key being revoked/rotated. i.e. only the key owner can revoke these.

Node Key Revocation

This is primarily a key rotation mechanism and we insist nodes rotate keys when being relocated, promoted or demoted. This gives us a trace of a node key history from its first Join . As above, but note the network can Kill the key.

key == EDPubKeyName + tag(02) // XorUrl
content ==
enum { Rotate: NewEDPubKey, Signature // of key + new key,
       Kill: (SectionKey, SectionSig), 
     }

Here a node can rotate his key (only once) proving to any network section he has done this exactly once. The network can kill this key in the case of bad behaviour. ( @qi.ma this prevents the Sybil attack on relocation/demote/promote). Note: a new node joining will not have rotated a key and this packet will not exist as there is no previous key. On the first promotion, this packet has to exist to rotate from his initial key.

DBC key Revocation

Here we assume single use keys. This means a key is spent exactly once, although that may mean several DBCs with the same owner being re-issued, that key is then dead. We assume all DBCs have a nonce along with the owner field, this allows owners to derive keys for their DBCs without knowing anything except the nonce and their base secret key.

This packet contains the Hash of all inputs + outputs. This is used to link the spend against a particular set of transactions.

key == BLSPubKeyName + tag(03) // XorUrl
content == Spend: TransactionHash, Signature, // of key + hash,

The client will create the DBC KRP as follows:

FOR EACH input
  CALL hash_extend
END

FOR EACH output
  CALL hash_extend
END

CALL hash_complete
CALL create KRP
CALL store KRP

When this packet is stored then the client can request a re-issue. For many different input “owners” then this packet need stored with the same TransactionHash at the location of each key and signed with the appropriate key.

Mint re-issue

IF sum inputs == sum outputs
  AND EVERY input owner has a `KRP` with the correct TransactionHash
  AND EVERY output key has NO `KRP`                  
  AND EVERY input `parent key` has a `KRP`
THEN sign all output DBCs  
ENDIF
12 Likes