aboutsummaryrefslogtreecommitdiff
path: root/include/odhtdb/Signature.hpp
blob: 92042f4417858a5680392fc85e9f33eb17534d11 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#pragma once

#include "DataView.hpp"
#include <stdexcept>
#include <unordered_map>

namespace odhtdb
{
    const int PUBLIC_KEY_NUM_BYTES = 32;
    const int PRIVATE_KEY_NUM_BYTES = 64;
    const int SIGNED_HASH_SIZE = 64;
    
    class InvalidSignatureKeySize : public std::runtime_error
    {
    public:
        InvalidSignatureKeySize(const std::string &errMsg) : std::runtime_error(errMsg) {}
    };
    
    class SignatureGenerationException : public std::runtime_error
    {
    public:
        SignatureGenerationException(const std::string &errMsg) : std::runtime_error(errMsg) {}
    };
    
    class DataSignException : public std::runtime_error
    {
    public:
        DataSignException(const std::string &errMsg) : std::runtime_error(errMsg) {}
    };
    
    class UnsignException : public std::runtime_error
    {
    public:
        UnsignException(const std::string &errMsg) : std::runtime_error(errMsg) {}
        virtual ~UnsignException(){}
    };
    
    class UnsignInvalidSizeException : public UnsignException
    {
    public:
        UnsignInvalidSizeException(const std::string &errMsg) : UnsignException(errMsg) {}
    };
    
    class UnsignWrongKeyException : public UnsignException
    {
    public:
        UnsignWrongKeyException(const std::string &errMsg) : UnsignException(errMsg) {}
    };
    
    namespace Signature
    {
        class PublicKey
        {
            friend class KeyPair;
        public:
            const static PublicKey ZERO;
            
            PublicKey();
            // Throws InvalidSignatureKeySize if size is not PUBLIC_KEY_NUM_BYTES
            PublicKey(const char *data, size_t size);
            PublicKey(const PublicKey &other);
            PublicKey& operator=(const PublicKey &other);
            
            char* getData() { return data; }
            const char* getData() const { return data; }
            size_t getSize() const { return PUBLIC_KEY_NUM_BYTES; }
            
            // Throws UnsignWrongKeyException if signed message was not signed using the matching private key of this public key.
            // Throws UnsignInvalidSizeException if signed message is too small (< SIGNED_HASH_SIZE).
            // Both exceptions are derived from UnsignException
            std::string unsign(const DataView &signedMessage) const;
            
            size_t operator()() const;
            bool operator==(const PublicKey &other) const;
            bool operator!=(const PublicKey &other) const;
            
            std::string toString() const;
        private:
            char data[PUBLIC_KEY_NUM_BYTES];
        };
        
        struct PublicKeyHasher
        {
            size_t operator()(const PublicKey &publicKey) const
            {
                return publicKey();
            }
        };
        
        template <typename ValueType>
        using MapPublicKey = std::unordered_map<PublicKey, ValueType, PublicKeyHasher>;
        
        class PrivateKey
        {
            friend class KeyPair;
        public:
            const static PrivateKey ZERO;
            
            PrivateKey();
            // Throws InvalidSignatureKeySize if size is not PRIVATE_KEY_NUM_BYTES
            PrivateKey(const char *data, size_t size);
            PrivateKey(const PrivateKey &other);
            PrivateKey& operator=(const PrivateKey &other);
            
            char* getData() { return data; }
            const char* getData() const { return data; }
            size_t getSize() const { return PRIVATE_KEY_NUM_BYTES; }
            
            bool operator==(const PrivateKey &other) const;
            bool operator!=(const PrivateKey &other) const;
            
            // Throws DataSignException if signing data failed for whatever reason. This wont happen unless there is an issue with the private key
            std::string sign(const DataView &dataToSign) const;
            std::string toString() const;
        private:
            char data[PRIVATE_KEY_NUM_BYTES];
        };
        
        class KeyPair
        {
        public:
            // Generate a new key pair, Throws SignatureGenerationException if generation of private/public key pair fails (should never happen)
            KeyPair();
            
            // Create a key pair from existing public and private key
            KeyPair(const PublicKey &publicKey, const PrivateKey &privateKey);
            
            KeyPair(const KeyPair &other);
            
            const PublicKey& getPublicKey() const { return publicKey; }
            const PrivateKey& getPrivateKey() const { return privateKey; }
        private:
            PublicKey publicKey;
            PrivateKey privateKey;
        };
    }
}