2.2.5 Cycle 5 - Signatures and Key Generation
Design
Objectives
The next module that needs implementing and introducing to the code base is the cryptography side, this is the part of the code that allows a node to sign things and to validate other wallet's transactions and signatures.
This will be done through either the RSA or DSA algorithm, as these are the most common and well-known signature algorithms and I can be sure that they work without having to design and test my own signature algorithm.
Usability Features
The ability to generate keys as needed if the user doesn't have any to reduce friction.
Once key pair has been either inputted or generated the user shouldn't have to worry about them during the Node's run time.
Key Variables
private_key
This is a private key that should not be shared and is used to sign data.
public_key
This is a publicly available key derived from the private key that can be used to validate that a specific private key produced a signature. Can also be used as an identifier for a wallet.
Choosing a Signature Algorithm
Before this part of the program can be designed and programmed, it is first required to choose a signature algorithm for generating signatures and validating transactions and therefore blocks.
The main two ways to do this are using either the RSA or DSA algorithms, both of which are considered safe and secure algorithms as of 2022, and can both be used for use case of which I will be using them for in this project.
Summary:
Primarily used for secure data transmission
Developed in 1977 by Ron Rivest, Adi Shamir and Leonard Adleman.
Uses the factorisation of product of two large primes for its mathematical security.
Faster Encryption than DSA
Slower Decryption than DSA
A basic diagram of how RSA works. (GeeksforGeeks, 2020)

Summary
Primarily used for secure digital signature and verification
Developed in 1991 by National Institute of Standards and Technology (NIST).
Uses modular exponentiation and discrete logarithm to ensure mathematical security.
Slower encryption compared to RSA.
Faster decryption than RSA.
A basic diagram of how DSA works. (GeeksforGeeks, 2020)

Due to DSA being primarily used and tested for signature and verification thus having being tested for the use case of which I will be using it for and having faster decryption than RSA - which will be used a lot more than encryption during the project - I will be using the DSA algorithm for this project.
Choosing How to Implement The Algorithm
Now that the DSA algorithm has been selected it's time to decide how to implement it: either through a library or from scratch.
This is a choice made possible by the fact that the DSA algorithm is open source and built using entirely mathematical functions so should theoretically be able to be implemented into any language.
However after looking into how the DSA algorithm works and what the V Language can handle, an issue is uncovered, one of the ways in which DSA stays secure is through the use of massively large prime numbers - currently recommended to be 2048 bits in length - however due to how Vlang integrates variables, in order to reach this size the number needs to be split up into batches of byte long values which would make processing the data required to use DSA a lot more complicated than it already is.
To clarify this doesn't mean it is impossible to write your own copy of the DSA algorithm in Vlang, it's just a lot more complicated than it would be in most other languages and puts it outside the time scope for this project.
Therefore as the 'from-scratch' method is off the table due to the complexity and therefore time scope I will instead be implementing DSA using the prebuilt crypto.ed25519 library, which includes a generate, sign and validate function all built in, although some wrapper functions will still need to be created to handle the loading/saving of these keys and ensuring they supply the data needed in the program and not an optional return like they do currently.
Design
All that is required in this stage is to create some wrapper functions for the libraries pre-existing functions to ensure that the data supplied to the rest of the node is what we expect it to be, as well as a custom validation function which will be used to check that a public and private key pair match such that some data can be signed and then validated using that pair.
Pseudocode
Wrapper functions:
Validation function
Development
Converting these designs to actual code is actually pretty simple and is just a case of turning the pseudocode into something more resembling V code. The largest change here is converting from the 'try-catch' structure of error handling into V's 'or' based handling.
One other thing worth mentioning in this section is the use of error codes, if you look at any part of the code that includes a function called exit you will see a number being passed as a parameter, this number represents a specific type of error and can be looked up in the ExitCodes.txt file supplied with the distribution files.
For example, at this specific point in the project the 'Cryptography Errors' section within ExitCodes.txt is the following:
Outcome
All the code in this cycle is within the file /packages/node/src/modules/cryptography/main.v found here.
Wrapper functions
Validation function
Challenges
The main challenge in this cycle was the attempted creation of a custom built DSA algorithm without using the library that I ended up using. I didn't mention this much in the `Choosing How to Implement The Algorithm` as all the reasoning in that sector for choosing a prebuilt library based system is correct, it's just how I came to understand those reasons that are the challenge.
This included the initial setup for a key generator, a probable prime generator (used to generate large numbers that are probably prime numbers to a high degree of probability) and some other utility files.
To see all the code written, and eventually scrapped, visit the archive file here.
Testing
Tests
1
Generate a key pair.
Keys to be generated and validated successfully without crashing.
As expected
Pass
2
Sign some random input data.
A signature to be generated without crashing.
As expected
Pass
3
Validate the data from test 2.
The data generated from test 2 should be validated successfully.
As expected
Pass
Evidence
Test 1 - Key generation tests

Test 2 - Key signature test

Test 3 - Key verification test

Last updated