View on GitHub

AMS

Algorand message standards

Algorand Message Standard for public voting

Summary

This document introduces the standard for public voting participation and calculation of voting results.

Abstract

The goal of this standard is to make the knowledge based pure democracy reality. This standard defines specification on how organization can propose voting, how organization can create trusted list of voters, how person can cast votes and how person can delegate other persons to vote on his behalf.

The goal of these conventions is to make any organization who seeks public voting the standard on how to vote.

Even if this standard is meant to be for algorand for the effeciency of the transactions and low transaction costs, it is not limitted to this blockchain. It can be used with any blockchain who support self transactions with specific payment, note field with at least 1000 bytes long message, and ability to search the network for specific transactions indexed by the amount, start of the note field, and/or the account.

Specification

The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC-2119.

JSON is the standard described in RFC-7159.

Note fields must be compliant with ARC-0002

Request for comments

Please comment or suggest pull request for this document here: https://github.com/scholtz/AMS/issues

Vote result calculation

Each account has specific voting power.

Single question results will always lead to multiple results:

This specifications does not interpret what level of acceptance of which type of results is acceptance criteria for questioner. Questioner SHOULD define his acceptance criteria in memorandum, constitution or company statute.

Note, that in the delegation extension, a voting power of an account if it does not vote, is transfered to a delegated account.

Simple balance results

Single account voting power for specific option is Token balance * On / (O1 + O2 .. Om)

Result for all options MUST be sum of all balance voting power of all accounts which has voted.

Quadratic balance results

Single account voting power for specific option is Token balance * On^2 / (O1^2 + O2^2 .. Om^2)

Result for all options MUST be sum of all balance voting power of all accounts which has voted.

Simple single account results

Single account voting power for specific option is 1 * On / (O1 + O2 .. Om)

Result for all options MUST be sum of all balance voting power of all accounts which has voted.

Quadratic single account results

Single account voting power for specific option is 1 * On^2 / (O1^2 + O2^2 .. Om^2)

Result for all options MUST be sum of all balance voting power of all accounts which has voted.

Simple trusted list results

Single account voting power from trusted list for specific option is 1 * On / (O1 + O2 .. Om) , else 0.

Result for all options MUST be sum of all balance voting power of all accounts which has voted.

Quadratic trusted list results

Single account voting power from trusted list for specific option is 1 * On^2 / (O1^2 + O2^2 .. Om^2) , else 0.

Result for all options MUST be sum of all balance voting power of all accounts which has voted.

Question

Question is the message stored on the blockchain.

The blockchain message MUST be self signed message, with amount 702 of basic tokens with specific note structure described below.

Question starts with avote-question/v2:j according to ARC-0002, following the json data.

If json data is not valid according to JSON standard, the question MUST NOT be shown to the users.

Json data MUST comply with following json schema:

{
  "$schema": "http://json-schema.org/draft-07/schema",
  "$id": "https://scholtz.github.io/AMS/AMS-0001/avote-question.json",
  "type": "object",
  "title": "Question schema",
  "description": "Knowledge based pure democracy question JSON document.",
  "default": {},
  "examples": [
      {
          "t": "Best project",
          "q": "Decide which project is the best\nA - AAA\nB - BBB\nC - CCC",
          "duration": 100,
          "category": "community",
          "o": {
              "A": "AAA",
              "B": "BBB",
              "C": "CCC"
          }
      }
  ],
  "required": [
      "t",
      "q",
      "duration",
      "category",
      "o"
  ],
  "properties": {
      "t": {
          "$id": "#/properties/t",
          "type": "string",
          "minLength": 1,
          "maxLength": 50,
          "title": "Title of the question",
          "description": "Title shown in the table of the questions",
          "default": "",
          "examples": [
              "Best project"
          ]
      },
      "q": {
          "$id": "#/properties/q",
          "type": "string",
          "minLength": 1,
          "maxLength": 500,
          "title": "Question text",
          "description": "The text of the question. MAY contain new lines specified as \n. ",
          "default": "",
          "examples": [
              "Decide which project is the best\nA - AAA\nB - BBB\nC - CCC"
          ]
      },
      "duration": {
          "$id": "#/properties/duration",
          "type": "integer",
          "minimum": 1,
          "maximum": 1000000,
          "title": "The duration how long the question is valid.",
          "description": "Duration is calculated in number of blocks. If there is 1, the question will have valid votes only in the block of inception, and the next block.",
          "default": 0,
          "examples": [
              100
          ]
      },
      "category": {
          "$id": "#/properties/category",
          "type": "string",
          "minLength": 1,
          "maxLength": 50,
          "title": "The category",
          "description": "The category of the question. Categories are managed by the questioner.",
          "default": "",
          "examples": [
              "community"
          ]
      },
      "e": {
          "$id": "#/properties/encryptionAddress",
          "type": "string",
          "minLength": 1,
          "maxLength": 50,
          "title": "Encryption address",
          "description": "The encryption address for encyption purposes according to Extension 3 of the specifications.",
          "default": "",
          "examples": [
              "56N75BOUSBSJALOWRQMJ7BU5JZHTEQCJP2PXHUCUXVOQJ4FPIKISV3UQB4"
          ]
      },
      "o": {
          "$id": "#/properties/o",
          "type": "object",
          "title": "Valid vote options",
          "description": "Valid vote options. Object of mapping from code to text of the question. The code will be used in vote cast to specify the answer.",
          "default": {},
          "examples": [
              {
                  "A": "AAA",
                  "B": "BBB",
                  "C": "CCC"
              }
          ],
          "additionalProperties": true
      }
  },
  "additionalProperties": false
}

Example:

avote-question/v1:j{"t":"Best project","q":"Decide which project is the best\nA - AAA\nB - BBB\nC - CCC","max":4410,"category":"community","o":{"A":"AAA","B":"BBB","C":"CCC"}}

Cast vote

Vote cast is the message stored on the blockchain.

The blockchain message MUST be self signed message, with amount 703 of basic tokens with specific note structure described below.

Vote cast starts with avote-vote/v1/{ShortQuestionId}:j according to ARC-0002, following the json data.

ShortQuestionId is the tx id of the message with the question for which this vote is answer. ShortQuestionId must be upper case substring from zero with length of 10 characters.

If json data is not valid according to JSON standard, or according to the schema below, the answer MUST NOT be calculated to the final results. If the vote cast code list does not mach with question option codes list, the answer MUST NOT be calculated to the final result.

The weights of the answers MUST be integer numbers in range between 0 and 1000 including. If the weights of results does not match with this criteria, the answer MUST NOT be calculated to the final result.

The voting power of the user is distributed to answers according to specified weights. For example in the example of distribution of {"A":35,"B":73,"C":20} the sum of the weights is 128, so the voting power of the casted vote for A is 35/128~=27,3%

Json data MUST comply with following json schema:

{
    "$schema": "http://json-schema.org/draft-07/schema",
    "$id": "https://scholtz.github.io/AMS/AMS-0001/avote-vote.json",
    "type": "object",
    "title": "Vote cast schema",
    "description": "Knowledge based pure democracy answer JSON document.",
    "default": {},
    "examples": [
        {"q":"CRID3AHJGGVE75UTDO5GI7PXM6PUD6WXB7BTAD3IPWFTMUXUKHDA","a":{"A":35,"B":73,"C":20}}
    ],
    "required": [
        "q",
        "a"
    ],
    "properties": {
        "q": {
            "$id": "#/properties/q",
            "type": "string",
            "minLength": 1,
            "maxLength": 60,
            "title": "The question id",
            "description": "Tx id of the question message from the blockchain",
            "default": "",
            "examples": [
                "CRID3AHJGGVE75UTDO5GI7PXM6PUD6WXB7BTAD3IPWFTMUXUKHDA"
            ]
        },
        "a": {
            "$id": "#/properties/a",
            "type": "object",
            "title": "Valid vote options",
            "description": "Valid vote options. Object of mapping from code to weight of the answer.",
            "default": {},
            "examples": [
                {"A":35,"B":73,"C":20}
            ],
            "additionalProperties": true
        }
    },
    "additionalProperties": false
}

Example:

avote-vote/v1/CRID3AHJGG:j{"q":"CRID3AHJGGVE75UTDO5GI7PXM6PUD6WXB7BTAD3IPWFTMUXUKHDA","a":{"A":35,"B":73,"C":20}}

Extension 1 - Vote delegation

Vote delegation is the extension for the voting system. It MAY not have to be used by the voting system implementation. If the voting system does not implement delegation, it should clearly state that voting system does not support delegation of the voting power. For knowledge based pure democracy voting system it is highly RECOMMENDED to use the delegation of the voting power.

Vote delegation is the delegation of the voting power from the delegee account to delegated account. If delegee does not vote, and delegated account votes for question, the delegated account votes with voting power of it self plus sum of voting power of all delegee accounts.

The delegation SHOULD be used in these usecases.

The delegation is transferable. If person A delegate his voting power to person B, and person B delegates his voting power to person C, and only person C casts the vote, the voting power of Person C is sum of Person A, Person B and Person C.

To prevent circular delegation, the maximum depth for vote delegation is 100 delegations.

If person A delegates 20 % of his voting power to person B, and 80 % to person C, and person A and B does not vote, and person C votes, the sum of voting power of person C is 80% of person A plus 100% of voting power of person C.

The blockchain message MUST be self signed message, with amount 701 of basic tokens with specific note structure described below.

Vote delegation note field in the blockchain MUST start with avote-delegation/v1:j according to ARC-0002, following the json data.

If json data is not valid according to JSON standard, or according to the schema below, the voting power MUST NOT be transfered.

The weights of the delegation between accounts MUST be integer numbers in range between 0 and 1000 including.

Json data MUST comply with following json schema:

{
    "$schema": "http://json-schema.org/draft-07/schema",
    "$id": "https://scholtz.github.io/AMS/AMS-0001/avote-delegation.json",
    "type": "object",
    "title": "Vote power delegation schema",
    "description": "Knowledge based pure democracy vote delegation JSON document.",
    "default": {},
    "examples": [
        {"d":{"any":{"TESTB74MOARQDWSX4433VWVNO4VJK3PDQWQ4JEOVQQTK3ZIX2MK3JF55TE":20,"TESTC2TMLDK273INHLXCSV235NFJ5LITNFDXZPU7JTZCVCBAZDUSJS4OPU":80},"finance":{"TESTDUUODZVXNO4YKEK4I5I6UU67ANYBJ77JZUI444VAD7V3TL26DVOMFA":1}}}
    ],
    "required": [
        "d"
    ],
    "properties": {
        "d": {
            "$id": "#/properties/d",
            "type": "object",
            "title": "Delegation of power",
            "description": "The object of categories with the object of accounts and the weights. Weight must be integer number in range from 0 to 1000 including.",
            "default": {},
            "examples": [
                {"any":{"TESTB74MOARQDWSX4433VWVNO4VJK3PDQWQ4JEOVQQTK3ZIX2MK3JF55TE":20,"TESTC2TMLDK273INHLXCSV235NFJ5LITNFDXZPU7JTZCVCBAZDUSJS4OPU":80},"finance":{"TESTDUUODZVXNO4YKEK4I5I6UU67ANYBJ77JZUI444VAD7V3TL26DVOMFA":1}}
            ],
            "additionalProperties": true
        }
    },
    "additionalProperties": false
}

Example:

avote-delegation/v1:j{"d":{"any":{"TESTB74MOARQDWSX4433VWVNO4VJK3PDQWQ4JEOVQQTK3ZIX2MK3JF55TE":20,"TESTC2TMLDK273INHLXCSV235NFJ5LITNFDXZPU7JTZCVCBAZDUSJS4OPU":80},"finance":{"TESTDUUODZVXNO4YKEK4I5I6UU67ANYBJ77JZUI444VAD7V3TL26DVOMFA":1}}}

Extension 2 - Trusted list

The trusted list is implementation extension which allows to calculate the results according to the trusted list specified by the questionaree.

If the voting system implementation does not implement trusted list extension, it should clearly state that the results are calculated only in the form 1 token = 1 vote.

The blockchain message MUST be self signed message, with amount 705 of basic tokens with specific note structure described below.

TL configuration message MUST start with avote-tl/v1:j according to ARC-0002, following the json data.

Trusted list contains all accounts which were added to the trusted list and which were not removed from the trusted list until the decision time of the voting.

The trusted list voting results calculates the same way as the 1 coin = 1 vote, with difference that if the account is on the trusted list, his voting power equals 1, and if the account is not on the trusted list, its voting power equals zero. The results for 1 coin = 1 vote are calculated in balance of the account at the final question block (the question entry block plus the duration stated in the question duration).

Decision snapshot of the trusted list for the vote calculation is the list of accounts in the trusted list in the final block when it is allowed to vote for the question. The additions or removal from the trusted list in the last question block MUST be processed. If the account is in the list of the accounts to be added as well as in the list to be removed in the single transaction, the removal MUST be applied.

{
    "$schema": "http://json-schema.org/draft-07/schema",
    "$id": "https://scholtz.github.io/AMS/AMS-0001/avote-tl.json",
    "type": "object",
    "title": "Trusted list management schema",
    "description": "Knowledge based pure democracy trusted list JSON document.",
    "default": {},
    "examples": [
        {
            "a": [
                "TESTAUZJU4JRAPUZBH4FCPYDLEWIFIFRPVILUZBSYP6IBZLYF6M6YVMMX4",
                "TESTB74MOARQDWSX4433VWVNO4VJK3PDQWQ4JEOVQQTK3ZIX2MK3JF55TE",
                "TESTC2TMLDK273INHLXCSV235NFJ5LITNFDXZPU7JTZCVCBAZDUSJS4OPU"
            ],
            "r": [
                "TESTQKYINIZLITDRT3BECSIPI77IQVCXG5I5SNOQLRO4PWSAQPSPCRHUXU"
            ]
        }
    ],
    "properties": {
        "a": {
            "$id": "#/properties/a",
            "type": "array",
            "title": "Trusted list additions",
            "description": "List of accounts to be added to the trusted list",
            "default": [],
            "examples": [
                [
                    "TESTAUZJU4JRAPUZBH4FCPYDLEWIFIFRPVILUZBSYP6IBZLYF6M6YVMMX4",
                    "TESTB74MOARQDWSX4433VWVNO4VJK3PDQWQ4JEOVQQTK3ZIX2MK3JF55TE"
                ]
            ],
            "additionalItems": false,
            "items": {
                "$id": "#/properties/a/items",
                "anyOf": [
                    {
                        "$id": "#/properties/a/items/anyOf/0",
                        "type": "string",
                        "title": "Account",
                        "minLength": 1,
                        "maxLength": 60,
                        "description": "The valid account",
                        "default": "",
                        "examples": [
                            "TESTAUZJU4JRAPUZBH4FCPYDLEWIFIFRPVILUZBSYP6IBZLYF6M6YVMMX4",
                            "TESTB74MOARQDWSX4433VWVNO4VJK3PDQWQ4JEOVQQTK3ZIX2MK3JF55TE"
                        ]
                    }
                ]
            }
        },
        "r": {
            "$id": "#/properties/r",
            "type": "array",
            "title": "Trusted list removals",
            "description": "List of accounts to be removed from the trusted list.",
            "default": [],
            "examples": [
                [
                    "TESTQKYINIZLITDRT3BECSIPI77IQVCXG5I5SNOQLRO4PWSAQPSPCRHUXU"
                ]
            ],
            "additionalItems": false,
            "items": {
                "$id": "#/properties/r/items",
                "anyOf": [
                    {
                        "$id": "#/properties/r/items/anyOf/0",
                        "type": "string",
                        "title": "Account",
                        "minLength": 1,
                        "maxLength": 60,
                        "description": "The valid account.",
                        "default": "",
                        "examples": [
                            "TESTQKYINIZLITDRT3BECSIPI77IQVCXG5I5SNOQLRO4PWSAQPSPCRHUXU"
                        ]
                    }
                ]
            }
        }
    },
    "additionalProperties": false
}
avote-tl/v1:j{"a":["TESTAUZJU4JRAPUZBH4FCPYDLEWIFIFRPVILUZBSYP6IBZLYF6M6YVMMX4","TESTB74MOARQDWSX4433VWVNO4VJK3PDQWQ4JEOVQQTK3ZIX2MK3JF55TE","TESTC2TMLDK273INHLXCSV235NFJ5LITNFDXZPU7JTZCVCBAZDUSJS4OPU"],"r":["TESTQKYINIZLITDRT3BECSIPI77IQVCXG5I5SNOQLRO4PWSAQPSPCRHUXU"]}

Result

Result is the message stored on the blockchain.

The blockchain message MUST be with amount 0 of basic tokens with specific note structure described below.

Sender of the message is auditor. Anybody can calculate results and be in the role of auditor.

If sender is the questioner, the results counted are considered final. Questioner in rare cases can fix results by submitting the result message again. The latest message of questioner is the decision making message.

Result starts with avote-result/v1/{ShortQuestionId}:j according to ARC-0002, following the json data.

ShortQuestionId is the tx id of the message with the question for which this vote is answer. ShortQuestionId must be upper case substring from zero with length of 10 characters.

Json data MUST comply with following json schema:

{
    "$schema": "http://json-schema.org/draft-07/schema",
    "$id": "https://scholtz.github.io/AMS/AMS-0001/avote-result.json",
    "type": "object",
    "title": "Vote result schema",
    "description": "Knowledge based pure democracy result JSON document.",
    "default": {},
    "examples": [
        {"q":"CRID3AHJGGVE75UTDO5GI7PXM6PUD6WXB7BTAD3IPWFTMUXUKHDA","r":{"sbr":{"A":3500.1,"B":7300.1,"C":2000.1},"qbr":{"A":3000.1,"B":7000.1,"C":2000.1},"ssar":{"A":50.1,"B":30.1,"C":40.1},"qsar":{"A":50.1,"B":30.1,"C":40.1},"stlr":{"A":5.1,"B":2.1,"C":1.1},"qtlr":{"A":5.1,"B":2.1,"C":1.1}}}
    ],
    "required": [
        "q",
        "r"
    ],
    "properties": {
        "q": {
            "$id": "#/properties/q",
            "type": "string",
            "minLength": 1,
            "maxLength": 60,
            "title": "The question id",
            "description": "Tx id of the question message from the blockchain",
            "default": "",
            "examples": [
                "CRID3AHJGGVE75UTDO5GI7PXM6PUD6WXB7BTAD3IPWFTMUXUKHDA"
            ]
        },
        "e": {
            "$id": "#/properties/encryption-private-key",
            "type": "string",
            "title": "Mnemonic of the encyption account for public voting validation",
            "examples": [
                {"fuel flock song credit cloud collect security danger knife fluid analyst roast short pizza more kingdom copy judge leave resist sock change wheel able story"}
            ],
        },
        "r": {
            "$id": "#/properties/r",
            "type": "object",
            "title": "Results",
            "examples": [
                {"sbr":{"A":3500.1,"B":7300.1,"C":2000.1},"qbr":{"A":3000.1,"B":7000.1,"C":2000.1},"ssar":{"A":50.1,"B":30.1,"C":40.1},"qsar":{"A":50.1,"B":30.1,"C":40.1},"stlr":{"A":5.1,"B":2.1,"C":1.1},"qtlr":{"A":5.1,"B":2.1,"C":1.1}}
            ],
            "additionalProperties": true,
            "properties": {
                "sbr": {
                    "$id": "#/properties/simple-balance-results",
                    "type": "object",
                    "title": "Simple balance results",
                    "examples": [
                        {"A":3500.1,"B":7300.1,"C":2000.1}
                    ],
                    "additionalProperties": true,
                },
                "qbr": {
                    "$id": "#/properties/quadratic-balance-results",
                    "type": "object",
                    "title": "Quadratic balance results",
                    "examples": [
                        {"A":3500.1,"B":7300.1,"C":2000.1}
                    ],
                    "additionalProperties": true,
                },
                "ssar": {
                    "$id": "#/properties/simple-single-account-results",
                    "type": "object",
                    "title": "Simple single account results",
                    "examples": [
                        {"A":3500.1,"B":7300.1,"C":2000.1}
                    ],
                    "additionalProperties": true,
                },
                "qsar": {
                    "$id": "#/properties/quadratic-single-account-results",
                    "type": "object",
                    "title": "Quadratic single account results",
                    "examples": [
                        {"A":3500.1,"B":7300.1,"C":2000.1}
                    ],
                    "additionalProperties": true,
                },
                "stlr": {
                    "$id": "#/properties/simple-trusted-list-results",
                    "type": "object",
                    "title": "Simple trusted list results",
                    "examples": [
                        {"A":3500.1,"B":7300.1,"C":2000.1}
                    ],
                    "additionalProperties": true,
                },
                "qtlr": {
                    "$id": "#/properties/quadratic-trusted-list-results",
                    "type": "object",
                    "title": "Quadratic trusted list results",
                    "examples": [
                        {"A":3500.1,"B":7300.1,"C":2000.1}
                    ],
                    "additionalProperties": true,
                },
            }
        }
    },
    "additionalProperties": false
}

Example:

avote-result/v1/CRID3AHJGG:j{"q":"CRID3AHJGGVE75UTDO5GI7PXM6PUD6WXB7BTAD3IPWFTMUXUKHDA","r":{"sbr":{"A":3500.1,"B":7300.1,"C":2000.1},"qbr":{"A":3000.1,"B":7000.1,"C":2000.1},"ssar":{"A":50.1,"B":30.1,"C":40.1},"qsar":{"A":50.1,"B":30.1,"C":40.1},"stlr":{"A":5.1,"B":2.1,"C":1.1},"qtlr":{"A":5.1,"B":2.1,"C":1.1}}}

Extension 3 - Encrypted voting

Purpose of the encrypted voting is to hide voter cast while the voting session is in progress.

Questioner for each question generates new Ed25519 mnemonic and stores it securly. Public key of this encryption account is called Question public key. If encryption of the messages is allowed, he publish encryption account address in the question message.

Curve25519XSalsa20Poly1305 is used to encrypt data. Voter encrypts the data in form of https://scholtz.github.io/AMS/AMS-0001/avote-vote.json and produces the json with the https://scholtz.github.io/AMS/AMS-0001/avote-vote-enc.json schema.

Encrypted vote cast is the message stored on the blockchain.

The blockchain message MUST be self signed message, with amount 703 of basic tokens with specific note structure described below.

Encrypted vote cast starts with avote-vote-enc/v1/{ShortQuestionId}:j according to ARC-0002, following the json data.

Questioner MAY publish his encryption keys to specific auditing account using ARC-0015 starndard. The content of the message is the mnemonic of the encryption account.

Questioner MAY publish the mnemonic of the encrypting account to the restult message. The questioner SHOULD publish the policy on weather he plans to publish the private encryption key on his website or in the question.

Json data MUST comply with following json schema:

{
    "$schema": "http://json-schema.org/draft-07/schema",
    "$id": "https://scholtz.github.io/AMS/AMS-0001/avote-vote-enc.json",
    "type": "object",
    "title": "Vote cast schema",
    "description": "Knowledge based pure democracy answer JSON document in encrypted form.",
    "default": {},
    "examples": [
        {"nonce":"ftGVJfrKJg+PPNCMbKPdLMN3OKNNnHDk","otPK":"w955HlFMM4e9dD1OQv31k4npHhs/w4QWc5Q1tcjxFkM=","cT":"O+M+3Y78RdxnMD6mJfNrfi8eT7dKmAFxJCq4z8Zb/lob+7tWptW1hPQWe60lmT64YLNdMSrPd9N0Wszr6AQFar5jbekHmM/YME/FEf4FjpYBLOwXK54MNy+8LOORNp1f"}
    ],
    "required": [
        "nonce",
        "otPK",
        "cT"
    ],
    "properties": {
        "nonce": {
            "$id": "#/properties/nonce",
            "type": "string",
            "title": "Nonce",
            "description": "Base64 data of random number. Byte length: nacl.box.nonceLength. const nonce = nacl.randomBytes(nacl.box.nonceLength);",
            "examples": [
                "ftGVJfrKJg+PPNCMbKPdLMN3OKNNnHDk"
            ],
            "additionalProperties": false
        },
        "otPK": {
            "$id": "#/properties/otPK",
            "type": "string",
            "title": "Encryption public key",
            "description": "Public key of randomly generated key pair when encoding the message. const otKeyPair = nacl.box.keyPair();",
            "examples": [
                "w955HlFMM4e9dD1OQv31k4npHhs/w4QWc5Q1tcjxFkM="
            ],
            "additionalProperties": false
        },
        "cT": {
            "$id": "#/properties/cT",
            "type": "string",
            "title": "Cipher text",
            "description": "Public key of randomly generated key pair when encoding the message. const cipherText = nacl.box(Buffer.from(encMsg),nonce,rcptPubKey,otKeyPair.secretKey)",
            "examples": [
                "O+M+3Y78RdxnMD6mJfNrfi8eT7dKmAFxJCq4z8Zb/lob+7tWptW1hPQWe60lmT64YLNdMSrPd9N0Wszr6AQFar5jbekHmM/YME/FEf4FjpYBLOwXK54MNy+8LOORNp1f"
            ],
            "additionalProperties": false
        }
    },
    "additionalProperties": false
}

Example:

avote-vote-enc/v1/XIP4Y7NMP2:j{"nonce":"ftGVJfrKJg+PPNCMbKPdLMN3OKNNnHDk","otPK":"w955HlFMM4e9dD1OQv31k4npHhs/w4QWc5Q1tcjxFkM=","cT":"O+M+3Y78RdxnMD6mJfNrfi8eT7dKmAFxJCq4z8Zb/lob+7tWptW1hPQWe60lmT64YLNdMSrPd9N0Wszr6AQFar5jbekHmM/YME/FEf4FjpYBLOwXK54MNy+8LOORNp1f"}