Ming Ke Ming (名可名) -- Account Module (Objective-C)
This document introduces a common Account Module for decentralized user identity authentication.
Copyright © 2018-2019 Albert Moky
0. Meta
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 |
---|---|
version | Meta Algorithm Version |
seed | Entity Name |
key | Public Key |
fingerprint | Signature to generate address |
0.0. Version
0x01
Default version0x02
BTC version0x03
Extended BTC version0x04
ETH version0x05
Extended ETH version
0.1. Seed
A string as same as ID.name for generate the fingerprint.
0.2. Key
A public key (PK) was binded to an ID by the Meta Algorithm.
0.3. Fingerprint
THe fingerprint field was generated by your private key and seed:
data = [seed dataUsingEncoding:NSUTF8StringEncoding];
fingerprint = [privateKey sign:data];
1. ID
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 |
number | Search Number |
The ID format is name@address[/terminal]
.
1.0. Type
The network type of a person is 8
, and group is 16
:
typedef NS_ENUM(UInt8, MKMNetworkID) {
/**
* Person Account
*/
MKMNetwork_Main = 0x08, // 0000 1000 (Person)
/**
* Virtual Groups
*/
MKMNetwork_Group = 0x10, // 0001 0000 (Multi-Persons)
MKMNetwork_Polylogue = 0x10, // 0001 0000 (Multi-Persons Chat, N < 100)
MKMNetwork_Chatroom = 0x30, // 0011 0000 (Multi-Persons Chat, N >= 100)
/**
* Network
*/
MKMNetwork_Provider = 0x76, // 0111 0110 (Service Provider)
MKMNetwork_Station = 0x88, // 1000 1000 (Server Node)
/**
* Internet of Things
*/
MKMNetwork_Thing = 0x80, // 1000 0000 (IoT)
MKMNetwork_Robot = 0xC8, // 1100 1000
};
typedef UInt8 MKMNetworkType;
1.1. Name
The Name field is a username, or just a random string for group:
- The length of name must more than 1 byte, less than 32 bytes;
- It should be composed by a-z, A-Z, 0-9, or charactors '_', '-', '.';
- It cannot contain key charactors('@', '/').
# Name examples
user_name = @"Albert.Moky";
group_name = @"Group-9527";
1.2. Address
The Address field was created with the Fingerprint in Meta and a Network ID:
static inline NSData * check_code(NSData *data) {
assert([data length] == 21);
data = [[data sha256] sha256];
return [data subdataWithRange:NSMakeRange(0, 4)];
}
static inline UInt32 user_number(NSData *cc) {
assert([cc length] == 4);
UInt32 number;
memcpy(&number, [cc bytes], sizeof(UInt32));
return number;
}
@implementation MKMAddressBTC
/**
* BTC address algorithm:
* digest = ripemd160(sha256(fingerprint));
* check_code = sha256(sha256(network + digest)).prefix(4);
* addr = base58_encode(network + digest + check_code);
*/
- (instancetype)initWithData:(NSData *)key
network:(MKMNetworkType)type {
NSString *string = nil;
UInt32 code = 0;
NSMutableData *data;
// 1. hash = ripemd160(sha256(CT))
NSData *hash = [[key sha256] ripemd160];
// 2. _h = network + hash
data = [[NSMutableData alloc] initWithBytes:&type length:1];
[data appendData:hash];
// 3. cc = sha256(sha256(_h)).prefix(4)
NSData *cc = check_code(data);
code = user_number(cc);
// 4. addr = base58_encode(_h + cc)
[data appendData:cc];
string = [data base58Encode];
if (self = [super initWithString:string]) {
self.network = type;
self.code = code;
}
return self;
}
@end
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.
1.3. Terminal
A resource identifier as Login Point.
1.4. Number
A Search Number is defined for easy remember. Its value is converted from the check code of the address. It's greater than 0 and smaller than 232 (4,294,967,296).
2. Samples
ID
# ID examples
ID1 = @"hulk@4YeVEN3aUnvC1DNUufCq1bs9zoBSJTzVEj"; // Immortal Hulk
ID2 = @"moki@4WDfe3zZ4T7opFSi3iDAKiuTnUHjxmXekk"; // Monkey King
Meta
/* Meta(JsON) for hulk@4YeVEN3aUnvC1DNUufCq1bs9zoBSJTzVEj */
{
version : 0x01,
seed : "hulk",
key : {
algorithm : "RSA",
data : "-----BEGIN PUBLIC KEY-----\nMIGJAoGBALB+vbUK48UU9rjlgnohQowME+3JtTb2hLPqtatVOW364/EKFq0/PSdnZVE9V2Zq+pbX7dj3nCS4pWnYf40ELH8wuDm0Tc4jQ70v4LgAcdy3JGTnWUGiCsY+0Z8kNzRkm3FJid592FL7ryzfvIzB9bjg8U2JqlyCVAyUYEnKv4lDAgMBAAE=\n-----END PUBLIC KEY-----",
// other parameters
keySize : 1024,
encryption : "PKCS1",
signature : "PKCS1v15SHA256"
},
fingerprint : "jIPGWpWSbR/DQH6ol3t9DSFkYroVHQDvtbJErmFztMUP2DgRrRSNWuoKY5Y26qL38wfXJQXjYiWqNWKQmQe/gK8M8NkU7lRwm+2nh9wSBYV6Q4WXsCboKbnM0+HVn9Vdfp21hMMGrxTX1pBPRbi0567ZjNQC8ffdW2WvQSoec2I="
}
(All data encode with BASE64 algorithm as default, excepts the address)