# Ming Ke Ming (名可名) -- Account Module (Python)
[](https://github.com/dimchat/mkm-py/blob/master/LICENSE)
[](https://github.com/dimchat/mkm-py/wiki)
[](https://github.com/dimchat/mkm-py/pulls)
[](https://github.com/dimchat/mkm-py/wiki)
This [document](https://github.com/moky/DIMP/blob/master/MingKeMing-Identity.md) introduces a common **Account Module** for decentralized user identity authentication.
Copyright © 2018-2019 Albert Moky
- [Meta](#meta)
- [Type](#meta-type)
- [Key](#meta-key)
- [Seed](#meta-seed)
- [Fingerprint](#meta-fingerprint)
- [ID](#id)
- [Type](#id-type)
- [Name](#id-name)
- [Address](#id-address)
- [Terminal](#id-terminal)
- [Samples](#samples)
## <span id="meta">0. Meta</span>
The **Meta** was generated by your **private key**, it can be used to build a new ID for entity, or verify the ID/PK pair.
It consists of 4 fields:
| Field | Description |
| ----------- | ----------------------------- |
| type | Meta Algorithm Version |
| key | Public Key |
| seed | Entity Name |
| fingerprint | Signature to generate address |
### <span id="meta-type">0.0. Meta Type</span>
* ```0x01``` **Default version**
* ```0x02``` BTC version
* ```0x03``` Extended BTC version
* ```0x04``` ETH version
* ```0x05``` Extended ETH version
### <span id="meta-key">0.1. Key</span>
A **public key** (PK) was bound to an ID by the **Meta Algorithm**.
### <span id="meta-seed">0.2. Seed</span>
A string as same as **ID.name** for generate the fingerprint.
### <span id="meta-fingerprint">0.3. Fingerprint</span>
THe **fingerprint** field was generated by your **private key** and **seed**:
````python
data = seed.encode('utf-8')
fingerprint = private_key.sign(data)
````
## <span id="id">1. ID</span>
The **ID** is used to identify an **entity**(user/group). It consists of 3 fields and 2 extended properties:
| Field | Description |
| ----------- | ----------------------------- |
| name | Same with meta.seed |
| address | Unique Identification |
| terminal | Login point, it's optional. |
| type | Network type |
The ID format is ```name@address[/terminal]```.
### <span id="id-type">1.0. ID Type</span>
The **network type** of a person is ```8```, and group is ```16```:
```python
class NetworkType(IntEnum):
# Person Account
MAIN = 0x08 # 0000 1000 (Person)
# Virtual Groups
GROUP = 0x10 # 0001 0000 (Multi-Persons)
POLYLOGUE = 0x10 # 0001 0000 (Multi-Persons Chat, N < 100)
CHATROOM = 0x30 # 0011 0000 (Multi-Persons Chat, N >= 100)
# Network
PROVIDER = 0x76 # 0111 0110 (Service Provider)
STATION = 0x88 # 1000 1000 (Server Node)
# Internet of Things
THING = 0x80 # 1000 0000 (IoT)
ROBOT = 0xC8 # 1100 1000
```
### <span id="id-name">1.1. Name</span>
The **Name** field is a username, or just a random string for group:
1. The length of name must more than 1 byte, less than 32 bytes;
2. It should be composed by a-z, A-Z, 0-9, or charactors '_', '-', '.';
3. It cannot contain key charactors('@', '/').
```python
# Name examples
user_name = "Albert.Moky"
group_name = "Group-9527"
```
### <span id="id-address">1.2. Address</span>
The **Address** field was created with the **Fingerprint** in Meta and a **Network ID**:
```python
def check_code(data: bytes) -> bytes:
# check code in BTC address
return sha256(sha256(data))[:4]
class BTCAddress(Address):
@classmethod
def new(cls, data: bytes, network: NetworkType=0) -> Address:
"""Generate address with fingerprint and network ID
:param data: fingerprint (signature/key.data)
:param network: address type
:return: Address object
"""
prefix = chr(network).encode('latin1')
digest = ripemd160(sha256(data))
code = check_code(prefix + digest)
address = base58_encode(prefix + digest + code)
return BTCAddress(address)
```
When you get a meta for the entity ID from the network,
you must verify it with the consensus algorithm before accept its **public key**.
### <span id="id-terminal">1.3. Terminal</span>
A resource identifier as **Login Point**.
## <span id="samples">2. Samples</span>
### ID
```python
# ID examples
ID1 = "hulk@4YeVEN3aUnvC1DNUufCq1bs9zoBSJTzVEj" # Immortal Hulk
ID2 = "moki@4WDfe3zZ4T7opFSi3iDAKiuTnUHjxmXekk" # Monkey King
```
### Meta
```javascript
/* Meta(JsON) for hulk@4YeVEN3aUnvC1DNUufCq1bs9zoBSJTzVEj */
{
"version" : 0x01,
"key" : {
"algorithm" : "RSA",
"data" : "-----BEGIN PUBLIC KEY-----\nMIGJAoGBALB+vbUK48UU9rjlgnohQowME+3JtTb2hLPqtatVOW364/EKFq0/PSdnZVE9V2Zq+pbX7dj3nCS4pWnYf40ELH8wuDm0Tc4jQ70v4LgAcdy3JGTnWUGiCsY+0Z8kNzRkm3FJid592FL7ryzfvIzB9bjg8U2JqlyCVAyUYEnKv4lDAgMBAAE=\n-----END PUBLIC KEY-----",
// other parameters
"mode" : "ECB",
"padding" : "PKCS1",
"digest" : "SHA256"
},
"seed" : "hulk",
"fingerprint" : "jIPGWpWSbR/DQH6ol3t9DSFkYroVHQDvtbJErmFztMUP2DgRrRSNWuoKY5Y26qL38wfXJQXjYiWqNWKQmQe/gK8M8NkU7lRwm+2nh9wSBYV6Q4WXsCboKbnM0+HVn9Vdfp21hMMGrxTX1pBPRbi0567ZjNQC8ffdW2WvQSoec2I="
}
```
(All data encode with **BASE64** algorithm as default, excepts the **address**)
Raw data
{
"_id": null,
"home_page": "https://github.com/dimchat/mkm-py",
"name": "mkm",
"maintainer": null,
"docs_url": null,
"requires_python": null,
"maintainer_email": null,
"keywords": null,
"author": "Albert Moky",
"author_email": "albert.moky@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/8b/9e/6357858abef552fab34c97903203d4dbfffee372e34af56bb101348b7df5/mkm-2.1.0.tar.gz",
"platform": null,
"description": "# Ming Ke Ming (\u540d\u53ef\u540d) -- Account Module (Python)\n\n[](https://github.com/dimchat/mkm-py/blob/master/LICENSE)\n[](https://github.com/dimchat/mkm-py/wiki)\n[](https://github.com/dimchat/mkm-py/pulls)\n[](https://github.com/dimchat/mkm-py/wiki)\n\nThis [document](https://github.com/moky/DIMP/blob/master/MingKeMing-Identity.md) introduces a common **Account Module** for decentralized user identity authentication.\n\nCopyright © 2018-2019 Albert Moky\n\n- [Meta](#meta)\n - [Type](#meta-type)\n - [Key](#meta-key)\n - [Seed](#meta-seed)\n - [Fingerprint](#meta-fingerprint)\n- [ID](#id)\n - [Type](#id-type)\n - [Name](#id-name)\n - [Address](#id-address)\n - [Terminal](#id-terminal)\n- [Samples](#samples)\n\n## <span id=\"meta\">0. Meta</span>\n\nThe **Meta** was generated by your **private key**, it can be used to build a new ID for entity, or verify the ID/PK pair.\n\nIt consists of 4 fields:\n\n| Field | Description |\n| ----------- | ----------------------------- |\n| type | Meta Algorithm Version |\n| key | Public Key |\n| seed | Entity Name |\n| fingerprint | Signature to generate address |\n\n### <span id=\"meta-type\">0.0. Meta Type</span>\n\n* ```0x01``` **Default version**\n* ```0x02``` BTC version\n* ```0x03``` Extended BTC version\n* ```0x04``` ETH version\n* ```0x05``` Extended ETH version\n\n### <span id=\"meta-key\">0.1. Key</span>\n\nA **public key** (PK) was bound to an ID by the **Meta Algorithm**.\n\n### <span id=\"meta-seed\">0.2. Seed</span>\n\nA string as same as **ID.name** for generate the fingerprint.\n\n### <span id=\"meta-fingerprint\">0.3. Fingerprint</span>\n\nTHe **fingerprint** field was generated by your **private key** and **seed**:\n\n````python\ndata = seed.encode('utf-8')\nfingerprint = private_key.sign(data)\n````\n\n## <span id=\"id\">1. ID</span>\nThe **ID** is used to identify an **entity**(user/group). It consists of 3 fields and 2 extended properties:\n\n| Field | Description |\n| ----------- | ----------------------------- |\n| name | Same with meta.seed |\n| address | Unique Identification |\n| terminal | Login point, it's optional. |\n| type | Network type |\n\nThe ID format is ```name@address[/terminal]```.\n\n### <span id=\"id-type\">1.0. ID Type</span>\n\nThe **network type** of a person is ```8```, and group is ```16```:\n\n```python\nclass NetworkType(IntEnum):\n # Person Account\n MAIN = 0x08 # 0000 1000 (Person)\n\n # Virtual Groups\n GROUP = 0x10 # 0001 0000 (Multi-Persons)\n POLYLOGUE = 0x10 # 0001 0000 (Multi-Persons Chat, N < 100)\n CHATROOM = 0x30 # 0011 0000 (Multi-Persons Chat, N >= 100)\n\n # Network\n PROVIDER = 0x76 # 0111 0110 (Service Provider)\n STATION = 0x88 # 1000 1000 (Server Node)\n\n # Internet of Things\n THING = 0x80 # 1000 0000 (IoT)\n ROBOT = 0xC8 # 1100 1000\n```\n\n### <span id=\"id-name\">1.1. Name</span>\nThe **Name** field is a username, or just a random string for group:\n\n1. The length of name must more than 1 byte, less than 32 bytes;\n2. It should be composed by a-z, A-Z, 0-9, or charactors '_', '-', '.';\n3. It cannot contain key charactors('@', '/').\n\n```python\n# Name examples\nuser_name = \"Albert.Moky\"\ngroup_name = \"Group-9527\"\n```\n\n### <span id=\"id-address\">1.2. Address</span>\n\nThe **Address** field was created with the **Fingerprint** in Meta and a **Network ID**:\n\n```python\ndef check_code(data: bytes) -> bytes:\n # check code in BTC address\n return sha256(sha256(data))[:4]\n\nclass BTCAddress(Address):\n\n @classmethod\n def new(cls, data: bytes, network: NetworkType=0) -> Address:\n \"\"\"Generate address with fingerprint and network ID\n :param data: fingerprint (signature/key.data)\n :param network: address type\n :return: Address object\n \"\"\"\n prefix = chr(network).encode('latin1')\n digest = ripemd160(sha256(data))\n code = check_code(prefix + digest)\n address = base58_encode(prefix + digest + code)\n return BTCAddress(address)\n```\n\nWhen you get a meta for the entity ID from the network,\nyou must verify it with the consensus algorithm before accept its **public key**.\n\n### <span id=\"id-terminal\">1.3. Terminal</span>\n\nA resource identifier as **Login Point**.\n\n## <span id=\"samples\">2. Samples</span>\n\n### ID\n\n```python\n# ID examples\nID1 = \"hulk@4YeVEN3aUnvC1DNUufCq1bs9zoBSJTzVEj\" # Immortal Hulk\nID2 = \"moki@4WDfe3zZ4T7opFSi3iDAKiuTnUHjxmXekk\" # Monkey King\n```\n\n### Meta\n\n```javascript\n/* Meta(JsON) for hulk@4YeVEN3aUnvC1DNUufCq1bs9zoBSJTzVEj */\n{\n \"version\" : 0x01,\n \"key\" : {\n \"algorithm\" : \"RSA\",\n \"data\" : \"-----BEGIN PUBLIC KEY-----\\nMIGJAoGBALB+vbUK48UU9rjlgnohQowME+3JtTb2hLPqtatVOW364/EKFq0/PSdnZVE9V2Zq+pbX7dj3nCS4pWnYf40ELH8wuDm0Tc4jQ70v4LgAcdy3JGTnWUGiCsY+0Z8kNzRkm3FJid592FL7ryzfvIzB9bjg8U2JqlyCVAyUYEnKv4lDAgMBAAE=\\n-----END PUBLIC KEY-----\",\n // other parameters\n \"mode\" : \"ECB\",\n \"padding\" : \"PKCS1\",\n \"digest\" : \"SHA256\"\n },\n \"seed\" : \"hulk\",\n \"fingerprint\" : \"jIPGWpWSbR/DQH6ol3t9DSFkYroVHQDvtbJErmFztMUP2DgRrRSNWuoKY5Y26qL38wfXJQXjYiWqNWKQmQe/gK8M8NkU7lRwm+2nh9wSBYV6Q4WXsCboKbnM0+HVn9Vdfp21hMMGrxTX1pBPRbi0567ZjNQC8ffdW2WvQSoec2I=\"\n}\n```\n\n(All data encode with **BASE64** algorithm as default, excepts the **address**)\n\n\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "A common identity module",
"version": "2.1.0",
"project_urls": {
"Homepage": "https://github.com/dimchat/mkm-py"
},
"split_keywords": [],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "497e2602353201a238d42be0332c39942d955a9d1801fd9363653c2e218985a7",
"md5": "65b1fc118993a10b90ac23f9d5c4d94f",
"sha256": "5575ec36cf6eb72b996b36c6d02a66192a436a8f830bbd02b12c4a658bd31911"
},
"downloads": -1,
"filename": "mkm-2.1.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "65b1fc118993a10b90ac23f9d5c4d94f",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": null,
"size": 61156,
"upload_time": "2024-08-29T17:15:27",
"upload_time_iso_8601": "2024-08-29T17:15:27.113572Z",
"url": "https://files.pythonhosted.org/packages/49/7e/2602353201a238d42be0332c39942d955a9d1801fd9363653c2e218985a7/mkm-2.1.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "8b9e6357858abef552fab34c97903203d4dbfffee372e34af56bb101348b7df5",
"md5": "a589716ea206387cec01676e9bddbdae",
"sha256": "f3bc37a3505c468239eae6d4da5167a69b823e09fc6e0df055c315025da904e0"
},
"downloads": -1,
"filename": "mkm-2.1.0.tar.gz",
"has_sig": false,
"md5_digest": "a589716ea206387cec01676e9bddbdae",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 29634,
"upload_time": "2024-08-29T17:15:28",
"upload_time_iso_8601": "2024-08-29T17:15:28.740464Z",
"url": "https://files.pythonhosted.org/packages/8b/9e/6357858abef552fab34c97903203d4dbfffee372e34af56bb101348b7df5/mkm-2.1.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-08-29 17:15:28",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "dimchat",
"github_project": "mkm-py",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "mkm"
}