-
Notifications
You must be signed in to change notification settings - Fork 1
Basic structure & algorithms
This is a general overview of the Shell Project's major Algorithms as they relate to blockchain. We borrow heavily from NEM's initial release and specification. This section will reference the algorithms and even lines of code if needed to describe implementation and provide references.
- https://docs.nem.io/en/address-components/address-components-2#generating-a-key-pair
- Also section 3.1 of https://www.nem.io/wp-content/themes/nem/files/NEM_techRef.pdf
- https://docs.nem.io/en/nem-sdk/private-key#6-1-create-private-keys
- https://github.com/QuantumMechanics/NEM-sdk/blob/master/src/crypto/keyPair.js
This section covers the fundamental building block of keypair generation.
- 1 - Generate random bytes into an array of fixed length;
- 2 - Convert the array into a hexadecimal string;
Note : All the outputs uses SHA256, instead of SHA512 as in NEM's original work.
Private keys can vary from 64 to 66 hexadecimal characters (starting with 00 in the case of 66 length).
According to NEM private key reference in https://docs.nem.io/en/nem-sdk/private-key#6-1-create-private-keys, there are 4 ways to creating private keys :
There are 4 choices to generate private keys, being :
1.1 - Type yourself 64 random hexadecimal string.
1.2 - Use included PRNG (pseudo-random number generator):
Regarding the use of libsodium library for cryptography, there is native calls of random number generators, as
described in https://download.libsodium.org/doc/generating_random_data :
* On Windows systems, the RtlGenRandom() function is used
* On OpenBSD and Bitrig, the arc4random() function is used
* On recent Linux kernels, the getrandom system call is used
* On other Unices, the /dev/urandom device is used
* If none of these options can safely be used, custom implementations can easily be hooked.
ubyte[] rBytes;
In NEM's structure and terms, key pairs holds representation for accounts keys (private, secret and public) to assign data or transactions.
Name | Type | Description |
---|---|---|
hexData | String | 64 or 66 hexadecimal characters |
ubyte[] privateKey = "aaaaaaaabbbbbbbbeeeeeeedddddx0861111111";
ubyte[] keyPair = generateKeyPair(privateKey);
Transactions relies on signing them with the keyPair object, such as any data segment.
ubyte[] signature;
keyPair(signature);
Signatures can be verified when having the signer public key, the data being signed and the signature itself.
Name | Type | Description |
---|---|---|
publicKey | string | The signer public key |
data | string | The data that were signed |
signature | string | The signature of the data |
Referencing https://github.com/QuantumMechanics/NEM-sdk/blob/master/src/crypto/keyPair.js, the following pseudo-code shows the flow of operations to generate keypairs :
var keypair =
var hash =
function convertHex() {
}
Transactions and wallets have addresses. We need a standard way to handle addressing.
Please reference details of NEM addressing: https://docs.nem.io/en/address-components
Let's borrow the best parts of this for the time being as an approach. Please define an address struct that handles this format:
The address of an account is a base-32 encoded triplet consisting of:
network byte: is it an address on the testnet or the mainnet?
160-bit hash of the public key
4 byte checksum, for detection of mistyped addresses
NEM's address api is defined here: https://www.nem.ninja/org.nem.core/org/nem/core/model/Address.html
In NEM's structure and architecture, accounts are generated from the combination of public and private Ed25519 keypairs, which has mutable state once transactions are validated and accepted by the network.
Accounts has in it's state the following items :
- Account balance
- Number of harvested blocks
- Height of the first transaction that referenced the account
- List of multisig accounts and list of cosignatories
- Information about delegated account status
- Importance and NCD (Nearly Completely Decomposable) aware rank
- Vested balance (crucial for PoI)