Skip to content

Basic structure & algorithms

Pedro Alves Batista edited this page Aug 23, 2018 · 6 revisions

Overview

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.

References

Public and Private Keypair Generation

This section covers the fundamental building block of keypair generation.

Public Key

  • 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 Key

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 :

1 - Create 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;

2 - Create keypairs

In NEM's structure and terms, key pairs holds representation for accounts keys (private, secret and public) to assign data or transactions.

Parameters
Name Type Description
hexData String 64 or 66 hexadecimal characters

Example

ubyte[] privateKey = "aaaaaaaabbbbbbbbeeeeeeedddddx0861111111";

ubyte[] keyPair = generateKeyPair(privateKey);

3 - Sign with keypair

Transactions relies on signing them with the keyPair object, such as any data segment.

Example
ubyte[] signature;

keyPair(signature);

4 - Verify a signature

Signatures can be verified when having the signer public key, the data being signed and the signature itself.

Parameters
Name Type Description
publicKey string The signer public key
data string The data that were signed
signature string The signature of the data

Code coverage

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() {

}

Addresses

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

Accounts

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.

Account state

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)