# 3.2 Pairwise Did Primer
# Tools
We will use the Commercio SDK, 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, the most relevant methods are:
- Chapter 3.3, IdHelper setDidDocument;
- Chapter 3.4, IdHelper requestDidPowerUp.
# Notations
Acronym | Meaning |
---|---|
I PU | Public Identity I . |
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 Government. |
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 - Send tokens to the Tumbler
The second step is to send the tokens (Chapter 2.9) to the public address of the centralized entity T
.
# 3 - Power Up Request
Only after you send the tokens to T
, finally you can create a Did power up request (Chapter 3.4).
# 3.1 - Step by step
- I
will create a JSON (signature_json
) containing the following information:
```json
{
"sender_did": "<User did>",
"pairwise_did": "<Pairwise Did address to power up>",
"timestamp": "<Timestamp>"
}
```
- I
retrive the Did of T
using public endpoint /government/tumbler
or by command cncli query government tumbler-address
.
- I
retrive the public key of T
resolving its DDO.
- I
calculate SHA-256 hash
of sender_did
, pairwise_did
and timestamp
concatenation.
- I
get sign(hash)
signing in format PKCS1v15 the hash
with the RSA private key associated to RSA public key inserted in the DDO.
- I
convert sign(hash)
in Base64 notation base64(sign(hash))
and use it to add signature
field.
- I
create a payload
JSON made as follow:
```json
{
"sender_did": "<User did>",
"pairwise_did": "<Pairwise Did to power up>",
"timestamp": "<Timestamp>",
"signature": "base64(sign(hash))",
}
```
- I
create a random AES-256 key F
.
- I
generate a random 96-bit nonce N
.
- I
encrypt the payload
using the F
AES-256 key.
I
remove all the white spaces and line ending characters.I
encrypt the resulting string bytes usingF
, obtainingciphertext
. Note that the AES encryption method must beAES-GCM
.I
concatenate bytes ofciphertext
andN
and encode the resulting bytes using the Base64 encoding method, obtainingproof
.
- I
encrypt the AES-256 key.
I
Encrypt theF
key bytes using the centralized system's RSA public key using PKCS1v15 mode.I
Encode the resulting bytes using the Base64 encoding method, obtainingproof_key
.
- I
will create the transaction message as follows:
```json
{
"type": "commercio/MsgRequestDidPowerUp",
"value": {
"claimant": "<Address of the Did to fund>",
"amount": [
{
"amount": "<Amount of coins to be sent>",
"denom": "<Denom of the coin to send>"
}
],
"proof": "<proof>",
"id": "<uuid>",
"proof_key": "<proof_key>"
}
}
```
- I
will send a transaction of the MsgRequestDidPowerUp
type.
```golang
type MsgRequestDidPowerUp struct {
Claimant sdk.AccAddress `json:"claimant"`
Amount sdk.Coins `json:"amount"`
Proof string `json:"proof"`
ID string `json:"id"`
ProofKey string `json:"proof_key"`
}
```
Claimant is the public Did of who made the request (therefore the Signer of MsgRequirePowerupDid)
Amount is the quantity sent in the powerup request
Proof is the proof sent in the powerup request
- T
will be constantly listening for new transactions of the type described above. Once a new transaction is observed, it will decrypt the proof_key
using its own private decryption key, obtainingF
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 sent 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 containing two messages:
```golang
type MsgSend struct {
FromAddress sdk.AccAddress `json:"from_address" yaml:"from_address"`
ToAddress sdk.AccAddress `json:"to_address" yaml:"to_address"`
Amount sdk.Coins `json:"amount" yaml:"amount"`
}
type MsgChangePowerUpStatus struct {
Recipient sdk.AccAddress `json:"recipient"`
PowerUpID string `json:"id"`
Status RequestStatus `json:"status"`
Signer sdk.AccAddress `json:"signer"`
}
```
Status has the value
approved
- If the transfer cannot be performed correctly, T
will perform an on-chain transaction with this message:
```golang
type MsgChangePowerUpStatus struct {
Recipient sdk.AccAddress `json:"recipient"`
PowerUpID string `json:"id"`
Status RequestStatus `json:"status"`
Signer sdk.AccAddress `json:"signer"`
}
```
Status has the value
rejected
Signer is the public
T DID