Cryptography

Symbol uses elliptic curve cryptography to verify the data integrity and to authenticate the signer’s identity.

Key pair

Elliptic curve cryptography is an approach to public key cryptography. The cryptographic system uses pairs of keys:

  • Private key: A random 256-bit integer used to sign entities known by the owner.
  • Public key: The public identifier of the key pair, which can be disseminated widely. It is used to prove that the entity was signed with the paired private key.

The public key is cryptographically derived from the private key. In particular, Symbol uses the Twisted Edwards curve with the digital signature algorithm named Ed25519 and hashing algorithm SHA-512.

You can find the implementation under the crypto module of catapult-server.

Signature

With a private key, the algorithm can sign messages producing 64-byte signatures. A signature is used to validate that a given key pair signed an entity just having the public key.

You can find the implementation to sign entities and verify them under the crypto module of catapult-server.

Address

Public keys can be shared in a shorter form as addresses. A Symbol address is a Base32 encoded triplet consisting of:

  • The network byte.
  • The 160-bit hash of the account’s public key.
  • The 3 byte checksum, to allow the quick recognition of mistyped addresses.

The following steps are performed to convert a public key to an address:

Address PublicKeyToAddress(const Key& publicKey, NetworkIdentifier networkIdentifier) {
        // step 1: sha3 hash of the public key
        Hash256 publicKeyHash;
        crypto::Sha3_256(publicKey, publicKeyHash);

        // step 2: ripemd160 hash of (1)
        Address decoded;
        crypto::Ripemd160(publicKeyHash, reinterpret_cast<Hash160&>(decoded[1]));

        // step 3: add network identifier byte in front of (2)
        decoded[0] = utils::to_underlying_type(networkIdentifier);

        // step 4: concatenate (3) and the checksum of (3)
        Hash256 step3Hash;
        crypto::Sha3_256(RawBuffer{ decoded.data(), Hash160::Size + 1 }, step3Hash);
        std::copy(step3Hash.cbegin(), step3Hash.cbegin() + Checksum_Size, decoded.begin() + Hash160::Size + 1);

        return decoded;
}

As you can see, it is possible to create an address without interacting with the blockchain. In fact, the blockchain only tracks addresses and public keys when they first appear in one transaction.

Continue: Block.