# 3.2 Pairwise Did Primer

# Tools

We will use the CommercioSDK, our own open source tool to format transactions to Commercio.network and The Sacco library, our own open source tool to sign and send transactions to any Cosmos SDK based blockchain, including Commercio.network.

# Functions and APIs

We will describe the system designed for the creation of pairwise identity.

This required the functions described in the following chapters. In particular:

  • Chapter 3.3, IdHelper setDidDocument(didDocument, wallet);
  • Chapter 3.4, IdHelper requestDidDeposit(recipient, amount, wallet);
  • Chapter 3.5, IdHelper requestDidPowerUp(pairwiseDid, amount, wallet).

# Notations

Acronym Meaning
I PU Public Identity I, verified by TSP A (authorized by Government)
I DID Decentralized Identifier associated with the identity I PU
I DDO Did Document associated with the I DID. Contains the Signature key and Encryption key associated with I PU
I VC Verifiable credentials associated with I PU. I controls other accounts which it will use to activate Pairwise Identity with its interlocutors. These identities are indicated with IPW1, IPW2 ... IPWn, all complete with the related Did Documents.
T Service that sells packages of cash and offers the possibility, upon indication of a public account detected, to carry out the power up of the accounts in a coupled way. T also has a public and verified account: T DID, T DDO and T VC from TSP B
C Challenge, calculated by I, in order to indicate a unique quantity (collision-free)

# Step by step sequence

# 1 - DDO Creation

First you need to create a I DDO associated with to I DID (Chapter 3.3).

# 2 - Deposit Request

When you have the I DDO , you can create a deposit request Chapter 3.4

In this way I through his account and public identity, opens a position on T, adding the sum K to T's account. Only T, through its decrytionKey, will be able to access the value C and verify that C has been calculated by I through the signature affixed with I PU SigningKey.

# 2.1 - Step by step

- I will create a JSON (signature_json) containing the following information:

{
  "recipient": "<Did address of the recipient>",
  "timestamp": "<Timestamp>"
}
1
2
3
4

- I will create the signature of signature_json, using the following procedure:

  1. Sort the JSON keys alphabetically
  2. Removes all spaces and carriage returns
  3. Sign the resulting string using your private signature key

- I will create a JSON (payload) containing the following information:

{
  "recipient": "<Did address of the recipient>",
  "timestamp": "<Timestamp>",
  "signature": "<Previously signed data, hex encoded>"
}
1
2
3
4
5

- I will generate a random AES-256 key. With this key, I will encrypt everything by following the procedure below:

  1. Remove all spaces and carriage returns from payload
  2. Digit everything using the symmetric key

and it will get the value of proof

- I will encrypt the AES-256 key using the public encryption key of T, obtaining encrypted_key. Then I will encode the encrypted_key via hex.

- I will create the transaction message as follows:

{
  "type": "commercio/MsgRequireDidDeposit",
  "value": {
    "signer": "<Acme S.p.A Did>",
    "amount": [
      {
        "denom": "uccc",
        "amount": "10000000"
      }
    ],
    "deposit_proof": "<proof>",
    "encryption_key": "<hex encoded encrypted AES-256 key>"
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

- I will send a transaction of the MsgRequireDidDeposit type.

type MsgRequireDidDeposit struct {
 Signer        sdk.AccAddress `json:"signer"`
 Amount        sdk.Coins      `json:"amount"`
 DepositProof  string         `json:"deposit_proof"`
 EncryptionKey string         `json:"encryption_key"`
}
1
2
3
4
5
6

- T will be constantly listening for new transactions of the type described above. Once a new transaction is observed, it will decrypt the encrypted_key using its own private decryption key, obtainingaes_key

- T will decrypt the payload usingaes_key and it will verify the signature contained in payload

- T will add the indicated amount to local balance associated with the recipient and it will send a transaction of the MsgSetDepositRequestHandled type.

type MsgSetDepositRequestHandled struct {
 DepositProof string         `json:"deposit_proof"`
 Claimant     sdk.AccAddress `json:"claimant"`
 Signer       sdk.AccAddress `json:"signer"`
}
1
2
3
4
5

# 3 - Power Up Request

Finally you can create a new Did power up request only after you made a did deposit request (Chapter 3.5).

# 3.1 - Step by step

- I will create a JSON (signature_json) containing the following information:

{
  "pairwise_did": "<Pairwise Did address to power up>",
  "timestamp": "<Timestamp>"
}
1
2
3
4

- I will create the signature of signature_json, using the following procedure:

  1. Sort the JSON keys alphabetically
  2. Removes all spaces and carriage returns
  3. Sign the resulting string using your private signature key

- I will create a JSON (payload) containing the following information:

{
  "pairwise_did": "<Pairwise Did to power up>",
  "timestamp": "<Timestamp>",
  "signature": "<Previously signed data, hex encoded>"
}
1
2
3
4
5

- I will generate a random AES-256 key. With this key, I encrypts everything by following the procedure below:

  1. Remove all spaces and carriage returns from the payload
  2. Digit everything using the symmetric key

and it will get the value of proof

- I will encrypt the AES-256 key using the public encryption key of T, obtaining encrypted_key. Then I encodes encrypted_key via hex.

- I will create the transaction message as follows:

{
  "type": "commercio/MsgRequirePowerupDid",
  "value": {
    "signer": "<Acme S.p.A Did>",
    "amount": [
      {
        "denom": "uccc",
        "amount": "10000000"
      }
    ],
    "deposit_proof": "<proof>",
    "encryption_key": "<hex encoded encrypted AES-256 key>"
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

- I will send a transaction of the MsgRequireDidDeposit type.

type MsgRequirePowerupDid struct {
 Amount        sdk.Coins      `json:"amount"`
 PowerupProof  string         `json:"powerup_proof"`
 EncryptionKey string         `json:"encryption_key"`
 Signer        sdk.AccAddress `json:"signer"`
}
1
2
3
4
5
6

- T will be constantly listening for new transactions of the type described above. Once a new transaction is observed, it will decrypt the encrypted_key using its own private decryption key, obtainingaes_key

- T will decrypt the payload usingaes_key and it will get I DDO through the I DID contained within the transaction

- T will extract the public signature key of I from the obtained I DDO and it will verify the signature contained in the payload

- T will verify that I has, in the local balance of T , a transferable amount of funds equal to or greater than that indicated in the transaction.

- If the transfer can be performed correctly, T will perform an on-chain transaction with this message:

type MsgPowerupDid struct {
 Amount       sdk.Coins      `json:"amount"`
 PowerupProof string         `json:"powerup_proof"`
 Claimant     sdk.AccAddress `json:"claimant"`
 Signer       sdk.AccAddress `json:"signer"`
}
1
2
3
4
5
6

- If the transfer cannot be performed correctly, T will perform an on-chain transaction with this message:

type MsgInvalidateDidPowerupRequest struct {
 PowerupProof string         `json:"powerup_proof"`
 Claimant     sdk.AccAddress `json:"claimant"`
 Signer       sdk.AccAddress `json:"signer"`
}
1
2
3
4
5

Claimant is the public Did of who made the request (therefore the Signer of MsgRequirePowerupDid)

Signer is the public T DID

Amount is the quantity sent in the powerup request

PowerupProof is the proof sent in the powerup request