A signature is normally composed of 3 elements:
- The payload that is signed
- The signature of the payload
- The public key that allows to check the signature
In datachain part of routing there are 2 structures that manage signatures and in each one only 2 of these elements are stored:
- struct Proof which doesn’t contain the payload
- struct Vote which doesn’t contain the public key
This means that some precautions are needed to be sure that any instance of these structures refers to a valid signature. The right way to implement this should be:
- check the signature in the constructor
- forbid creation outside the constructor (but cloning an existing one is OK)
- forbid modification
This way the compiler would automatically reject any attempts to create an invalid Proof or Vote in the code.
Unfortunately, these structures are not implemented like this. I don’t doubt that the instances created in Maidsafe code are valid, but this must be checked manually. Using this implementation would make it simpler to prove to external auditors that signatures stored in Proof or Vote instances are always valid.
Concretely the problems I see are:
-
Proof has no constructor and has public fields, which means that anywhere in the code this structure can be instantiated without verification of the signature.
-
Vote has:
- private fields
- a constructor that checks the signature
- but another constructor that doesn’t (fn compose)
- private fields
IMO the team should do the effort to implement these principles for a safer and provable code.