1 /*
2 * Copyright (c) 2013-2021, The PurpleI2P Project
3 *
4 * This file is part of Purple i2pd project and licensed under BSD3
5 *
6 * See full license text in LICENSE file at top of project tree
7 */
8 
9 #ifndef SIGNATURE_H__
10 #define SIGNATURE_H__
11 
12 #include <inttypes.h>
13 #include <string.h>
14 #include <openssl/dsa.h>
15 #include <openssl/ec.h>
16 #include <openssl/ecdsa.h>
17 #include <openssl/evp.h>
18 #include "Crypto.h"
19 #include "Ed25519.h"
20 #include "Gost.h"
21 
22 namespace i2p
23 {
24 namespace crypto
25 {
26 	class Verifier
27 	{
28 		public:
29 
~Verifier()30 			virtual ~Verifier () {};
31 			virtual bool Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const = 0;
32 			virtual size_t GetPublicKeyLen () const = 0;
33 			virtual size_t GetSignatureLen () const = 0;
GetPrivateKeyLen()34 			virtual size_t GetPrivateKeyLen () const { return GetSignatureLen ()/2; };
35 			virtual void SetPublicKey (const uint8_t * signingKey) = 0;
36 	};
37 
38 	class Signer
39 	{
40 		public:
41 
~Signer()42 			virtual ~Signer () {};
43 			virtual void Sign (const uint8_t * buf, int len, uint8_t * signature) const = 0;
44 	};
45 
46 	const size_t DSA_PUBLIC_KEY_LENGTH = 128;
47 	const size_t DSA_SIGNATURE_LENGTH = 40;
48 	const size_t DSA_PRIVATE_KEY_LENGTH = DSA_SIGNATURE_LENGTH/2;
49 	class DSAVerifier: public Verifier
50 	{
51 		public:
52 
DSAVerifier()53 			DSAVerifier ()
54 			{
55 				m_PublicKey = CreateDSA ();
56 			}
57 
SetPublicKey(const uint8_t * signingKey)58 			void SetPublicKey (const uint8_t * signingKey)
59 			{
60 				DSA_set0_key (m_PublicKey, BN_bin2bn (signingKey, DSA_PUBLIC_KEY_LENGTH, NULL), NULL);
61 			}
62 
~DSAVerifier()63 			~DSAVerifier ()
64 			{
65 				DSA_free (m_PublicKey);
66 			}
67 
Verify(const uint8_t * buf,size_t len,const uint8_t * signature)68 			bool Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const
69 			{
70 				// calculate SHA1 digest
71 				uint8_t digest[20];
72 				SHA1 (buf, len, digest);
73 				// signature
74 				DSA_SIG * sig = DSA_SIG_new();
75 				DSA_SIG_set0 (sig, BN_bin2bn (signature, DSA_SIGNATURE_LENGTH/2, NULL), BN_bin2bn (signature + DSA_SIGNATURE_LENGTH/2, DSA_SIGNATURE_LENGTH/2, NULL));
76 				// DSA verification
77 				int ret = DSA_do_verify (digest, 20, sig, m_PublicKey);
78 				DSA_SIG_free(sig);
79 				return ret;
80 			}
81 
GetPublicKeyLen()82 			size_t GetPublicKeyLen () const { return DSA_PUBLIC_KEY_LENGTH; };
GetSignatureLen()83 			size_t GetSignatureLen () const { return DSA_SIGNATURE_LENGTH; };
84 
85 		private:
86 
87 			DSA * m_PublicKey;
88 	};
89 
90 	class DSASigner: public Signer
91 	{
92 		public:
93 
DSASigner(const uint8_t * signingPrivateKey,const uint8_t * signingPublicKey)94 			DSASigner (const uint8_t * signingPrivateKey, const uint8_t * signingPublicKey)
95 			// openssl 1.1 always requires DSA public key even for signing
96 			{
97 				m_PrivateKey = CreateDSA ();
98 				DSA_set0_key (m_PrivateKey, BN_bin2bn (signingPublicKey, DSA_PUBLIC_KEY_LENGTH, NULL), BN_bin2bn (signingPrivateKey, DSA_PRIVATE_KEY_LENGTH, NULL));
99 			}
100 
~DSASigner()101 			~DSASigner ()
102 			{
103 				DSA_free (m_PrivateKey);
104 			}
105 
Sign(const uint8_t * buf,int len,uint8_t * signature)106 			void Sign (const uint8_t * buf, int len, uint8_t * signature) const
107 			{
108 				uint8_t digest[20];
109 				SHA1 (buf, len, digest);
110 				DSA_SIG * sig = DSA_do_sign (digest, 20, m_PrivateKey);
111 				const BIGNUM * r, * s;
112 				DSA_SIG_get0 (sig, &r, &s);
113 				bn2buf (r, signature, DSA_SIGNATURE_LENGTH/2);
114 				bn2buf (s, signature + DSA_SIGNATURE_LENGTH/2, DSA_SIGNATURE_LENGTH/2);
115 				DSA_SIG_free(sig);
116 			}
117 
118 		private:
119 
120 			DSA * m_PrivateKey;
121 	};
122 
CreateDSARandomKeys(uint8_t * signingPrivateKey,uint8_t * signingPublicKey)123 	inline void CreateDSARandomKeys (uint8_t * signingPrivateKey, uint8_t * signingPublicKey)
124 	{
125 		DSA * dsa = CreateDSA ();
126 		DSA_generate_key (dsa);
127 		const BIGNUM * pub_key, * priv_key;
128 		DSA_get0_key(dsa, &pub_key, &priv_key);
129 		bn2buf (priv_key, signingPrivateKey, DSA_PRIVATE_KEY_LENGTH);
130 		bn2buf (pub_key, signingPublicKey, DSA_PUBLIC_KEY_LENGTH);
131 		DSA_free (dsa);
132 	}
133 
134 	struct SHA256Hash
135 	{
CalculateHashSHA256Hash136 		static void CalculateHash (const uint8_t * buf, size_t len, uint8_t * digest)
137 		{
138 			SHA256 (buf, len, digest);
139 		}
140 
141 		enum { hashLen = 32 };
142 	};
143 
144 	struct SHA384Hash
145 	{
CalculateHashSHA384Hash146 		static void CalculateHash (const uint8_t * buf, size_t len, uint8_t * digest)
147 		{
148 			SHA384 (buf, len, digest);
149 		}
150 
151 		enum { hashLen = 48 };
152 	};
153 
154 	struct SHA512Hash
155 	{
CalculateHashSHA512Hash156 		static void CalculateHash (const uint8_t * buf, size_t len, uint8_t * digest)
157 		{
158 			SHA512 (buf, len, digest);
159 		}
160 
161 		enum { hashLen = 64 };
162 	};
163 
164 	// EcDSA
165 	template<typename Hash, int curve, size_t keyLen>
166 	class ECDSAVerifier: public Verifier
167 	{
168 		public:
169 
ECDSAVerifier()170 			ECDSAVerifier ()
171 			{
172 				m_PublicKey = EC_KEY_new_by_curve_name (curve);
173 			}
174 
SetPublicKey(const uint8_t * signingKey)175 			void SetPublicKey (const uint8_t * signingKey)
176 			{
177 				BIGNUM * x = BN_bin2bn (signingKey, keyLen/2, NULL);
178 				BIGNUM * y = BN_bin2bn (signingKey + keyLen/2, keyLen/2, NULL);
179 				EC_KEY_set_public_key_affine_coordinates (m_PublicKey, x, y);
180 				BN_free (x); BN_free (y);
181 			}
182 
~ECDSAVerifier()183 			~ECDSAVerifier ()
184 			{
185 				EC_KEY_free (m_PublicKey);
186 			}
187 
Verify(const uint8_t * buf,size_t len,const uint8_t * signature)188 			bool Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const
189 			{
190 				uint8_t digest[Hash::hashLen];
191 				Hash::CalculateHash (buf, len, digest);
192 				ECDSA_SIG * sig = ECDSA_SIG_new();
193 				auto r = BN_bin2bn (signature, GetSignatureLen ()/2, NULL);
194 				auto s = BN_bin2bn (signature + GetSignatureLen ()/2, GetSignatureLen ()/2, NULL);
195 				ECDSA_SIG_set0(sig, r, s);
196 				// ECDSA verification
197 				int ret = ECDSA_do_verify (digest, Hash::hashLen, sig, m_PublicKey);
198 				ECDSA_SIG_free(sig);
199 				return ret;
200 			}
201 
GetPublicKeyLen()202 			size_t GetPublicKeyLen () const { return keyLen; };
GetSignatureLen()203 			size_t GetSignatureLen () const { return keyLen; }; // signature length = key length
204 
205 
206 		private:
207 
208 			EC_KEY * m_PublicKey;
209 	};
210 
211 	template<typename Hash, int curve, size_t keyLen>
212 	class ECDSASigner: public Signer
213 	{
214 		public:
215 
ECDSASigner(const uint8_t * signingPrivateKey)216 			ECDSASigner (const uint8_t * signingPrivateKey)
217 			{
218 				m_PrivateKey = EC_KEY_new_by_curve_name (curve);
219 				EC_KEY_set_private_key (m_PrivateKey, BN_bin2bn (signingPrivateKey, keyLen/2, NULL));
220 			}
221 
~ECDSASigner()222 			~ECDSASigner ()
223 			{
224 				EC_KEY_free (m_PrivateKey);
225 			}
226 
Sign(const uint8_t * buf,int len,uint8_t * signature)227 			void Sign (const uint8_t * buf, int len, uint8_t * signature) const
228 			{
229 				uint8_t digest[Hash::hashLen];
230 				Hash::CalculateHash (buf, len, digest);
231 				ECDSA_SIG * sig = ECDSA_do_sign (digest, Hash::hashLen, m_PrivateKey);
232 				const BIGNUM * r, * s;
233 				ECDSA_SIG_get0 (sig, &r, &s);
234 				// signatureLen = keyLen
235 				bn2buf (r, signature, keyLen/2);
236 				bn2buf (s, signature + keyLen/2, keyLen/2);
237 				ECDSA_SIG_free(sig);
238 			}
239 
240 		private:
241 
242 			EC_KEY * m_PrivateKey;
243 	};
244 
CreateECDSARandomKeys(int curve,size_t keyLen,uint8_t * signingPrivateKey,uint8_t * signingPublicKey)245 	inline void CreateECDSARandomKeys (int curve, size_t keyLen, uint8_t * signingPrivateKey, uint8_t * signingPublicKey)
246 	{
247 		EC_KEY * signingKey = EC_KEY_new_by_curve_name (curve);
248 		EC_KEY_generate_key (signingKey);
249 		bn2buf (EC_KEY_get0_private_key (signingKey), signingPrivateKey, keyLen/2);
250 		BIGNUM * x = BN_new(), * y = BN_new();
251 		EC_POINT_get_affine_coordinates_GFp (EC_KEY_get0_group(signingKey),
252 			EC_KEY_get0_public_key (signingKey), x, y, NULL);
253 		bn2buf (x, signingPublicKey, keyLen/2);
254 		bn2buf (y, signingPublicKey + keyLen/2, keyLen/2);
255 		BN_free (x); BN_free (y);
256 		EC_KEY_free (signingKey);
257 	}
258 
259 // ECDSA_SHA256_P256
260 	const size_t ECDSAP256_KEY_LENGTH = 64;
261 	typedef ECDSAVerifier<SHA256Hash, NID_X9_62_prime256v1, ECDSAP256_KEY_LENGTH> ECDSAP256Verifier;
262 	typedef ECDSASigner<SHA256Hash, NID_X9_62_prime256v1, ECDSAP256_KEY_LENGTH> ECDSAP256Signer;
263 
CreateECDSAP256RandomKeys(uint8_t * signingPrivateKey,uint8_t * signingPublicKey)264 	inline void CreateECDSAP256RandomKeys (uint8_t * signingPrivateKey, uint8_t * signingPublicKey)
265 	{
266 		CreateECDSARandomKeys (NID_X9_62_prime256v1, ECDSAP256_KEY_LENGTH, signingPrivateKey, signingPublicKey);
267 	}
268 
269 // ECDSA_SHA384_P384
270 	const size_t ECDSAP384_KEY_LENGTH = 96;
271 	typedef ECDSAVerifier<SHA384Hash, NID_secp384r1, ECDSAP384_KEY_LENGTH> ECDSAP384Verifier;
272 	typedef ECDSASigner<SHA384Hash, NID_secp384r1, ECDSAP384_KEY_LENGTH> ECDSAP384Signer;
273 
CreateECDSAP384RandomKeys(uint8_t * signingPrivateKey,uint8_t * signingPublicKey)274 	inline void CreateECDSAP384RandomKeys (uint8_t * signingPrivateKey, uint8_t * signingPublicKey)
275 	{
276 		CreateECDSARandomKeys (NID_secp384r1, ECDSAP384_KEY_LENGTH, signingPrivateKey, signingPublicKey);
277 	}
278 
279 // ECDSA_SHA512_P521
280 	const size_t ECDSAP521_KEY_LENGTH = 132;
281 	typedef ECDSAVerifier<SHA512Hash, NID_secp521r1, ECDSAP521_KEY_LENGTH> ECDSAP521Verifier;
282 	typedef ECDSASigner<SHA512Hash, NID_secp521r1, ECDSAP521_KEY_LENGTH> ECDSAP521Signer;
283 
CreateECDSAP521RandomKeys(uint8_t * signingPrivateKey,uint8_t * signingPublicKey)284 	inline void CreateECDSAP521RandomKeys (uint8_t * signingPrivateKey, uint8_t * signingPublicKey)
285 	{
286 		CreateECDSARandomKeys (NID_secp521r1, ECDSAP521_KEY_LENGTH, signingPrivateKey, signingPublicKey);
287 	}
288 
289 
290 	// EdDSA
291 	class EDDSA25519Verifier: public Verifier
292 	{
293 		public:
294 
295 			EDDSA25519Verifier ();
296 			void SetPublicKey (const uint8_t * signingKey);
297 			~EDDSA25519Verifier ();
298 
299 			bool Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const;
300 
GetPublicKeyLen()301 			size_t GetPublicKeyLen () const { return EDDSA25519_PUBLIC_KEY_LENGTH; };
GetSignatureLen()302 			size_t GetSignatureLen () const { return EDDSA25519_SIGNATURE_LENGTH; };
303 
304 		private:
305 
306 #if OPENSSL_EDDSA
307 			EVP_MD_CTX * m_MDCtx;
308 #else
309 			EDDSAPoint m_PublicKey;
310 			uint8_t m_PublicKeyEncoded[EDDSA25519_PUBLIC_KEY_LENGTH];
311 #endif
312 	};
313 
314 	class EDDSA25519SignerCompat: public Signer
315 	{
316 		public:
317 
318 			EDDSA25519SignerCompat (const uint8_t * signingPrivateKey, const uint8_t * signingPublicKey = nullptr);
319 			// we pass signingPublicKey to check if it matches private key
320 			~EDDSA25519SignerCompat ();
321 
322 			void Sign (const uint8_t * buf, int len, uint8_t * signature) const;
GetPublicKey()323 			const uint8_t * GetPublicKey () const { return m_PublicKeyEncoded; }; // for keys creation
324 
325 		private:
326 
327 			uint8_t m_ExpandedPrivateKey[64];
328 			uint8_t m_PublicKeyEncoded[EDDSA25519_PUBLIC_KEY_LENGTH];
329 	};
330 
331 #if OPENSSL_EDDSA
332 	class EDDSA25519Signer: public Signer
333 	{
334 		public:
335 
336 			EDDSA25519Signer (const uint8_t * signingPrivateKey, const uint8_t * signingPublicKey = nullptr);
337 			// we pass signingPublicKey to check if it matches private key
338 			~EDDSA25519Signer ();
339 
340 			void Sign (const uint8_t * buf, int len, uint8_t * signature) const;
341 
342 		private:
343 
344 			EVP_MD_CTX * m_MDCtx;
345 			EDDSA25519SignerCompat * m_Fallback;
346 	};
347 #else
348 
349 	typedef EDDSA25519SignerCompat EDDSA25519Signer;
350 
351 #endif
352 
CreateEDDSA25519RandomKeys(uint8_t * signingPrivateKey,uint8_t * signingPublicKey)353 	inline void CreateEDDSA25519RandomKeys (uint8_t * signingPrivateKey, uint8_t * signingPublicKey)
354 	{
355 #if OPENSSL_EDDSA
356 		EVP_PKEY *pkey = NULL;
357 		EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_id (EVP_PKEY_ED25519, NULL);
358 		EVP_PKEY_keygen_init (pctx);
359 		EVP_PKEY_keygen (pctx, &pkey);
360 		EVP_PKEY_CTX_free (pctx);
361 		size_t len = EDDSA25519_PUBLIC_KEY_LENGTH;
362 		EVP_PKEY_get_raw_public_key (pkey, signingPublicKey, &len);
363 		len = EDDSA25519_PRIVATE_KEY_LENGTH;
364 		EVP_PKEY_get_raw_private_key (pkey, signingPrivateKey, &len);
365 		EVP_PKEY_free (pkey);
366 #else
367 		RAND_bytes (signingPrivateKey, EDDSA25519_PRIVATE_KEY_LENGTH);
368 		EDDSA25519Signer signer (signingPrivateKey);
369 		memcpy (signingPublicKey, signer.GetPublicKey (), EDDSA25519_PUBLIC_KEY_LENGTH);
370 #endif
371 	}
372 
373 
374 	// ГОСТ Р 34.11
375 	struct GOSTR3411_256_Hash
376 	{
CalculateHashGOSTR3411_256_Hash377 		static void CalculateHash (const uint8_t * buf, size_t len, uint8_t * digest)
378 		{
379 			GOSTR3411_2012_256 (buf, len, digest);
380 		}
381 
382 		enum { hashLen = 32 };
383 	};
384 
385 	struct GOSTR3411_512_Hash
386 	{
CalculateHashGOSTR3411_512_Hash387 		static void CalculateHash (const uint8_t * buf, size_t len, uint8_t * digest)
388 		{
389 			GOSTR3411_2012_512 (buf, len, digest);
390 		}
391 
392 		enum { hashLen = 64 };
393 	};
394 
395 	// ГОСТ Р 34.10
396 	const size_t GOSTR3410_256_PUBLIC_KEY_LENGTH = 64;
397 	const size_t GOSTR3410_512_PUBLIC_KEY_LENGTH = 128;
398 
399 	template<typename Hash>
400 	class GOSTR3410Verifier: public Verifier
401 	{
402 		public:
403 
404 			enum { keyLen = Hash::hashLen };
405 
GOSTR3410Verifier(GOSTR3410ParamSet paramSet)406 			GOSTR3410Verifier (GOSTR3410ParamSet paramSet):
407 				m_ParamSet (paramSet), m_PublicKey (nullptr)
408 			{
409 			}
410 
SetPublicKey(const uint8_t * signingKey)411 			void SetPublicKey (const uint8_t * signingKey)
412 			{
413 				BIGNUM * x = BN_bin2bn (signingKey, GetPublicKeyLen ()/2, NULL);
414 				BIGNUM * y = BN_bin2bn (signingKey + GetPublicKeyLen ()/2, GetPublicKeyLen ()/2, NULL);
415 				m_PublicKey = GetGOSTR3410Curve (m_ParamSet)->CreatePoint (x, y);
416 				BN_free (x); BN_free (y);
417 			}
~GOSTR3410Verifier()418 			~GOSTR3410Verifier ()
419 			{
420 				if (m_PublicKey) EC_POINT_free (m_PublicKey);
421 			}
422 
Verify(const uint8_t * buf,size_t len,const uint8_t * signature)423 			bool Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const
424 			{
425 				uint8_t digest[Hash::hashLen];
426 				Hash::CalculateHash (buf, len, digest);
427 				BIGNUM * d = BN_bin2bn (digest, Hash::hashLen, nullptr);
428 				BIGNUM * r = BN_bin2bn (signature, GetSignatureLen ()/2, NULL);
429 				BIGNUM * s = BN_bin2bn (signature + GetSignatureLen ()/2, GetSignatureLen ()/2, NULL);
430 				bool ret = GetGOSTR3410Curve (m_ParamSet)->Verify (m_PublicKey, d, r, s);
431 				BN_free (d); BN_free (r); BN_free (s);
432 				return ret;
433 			}
434 
GetPublicKeyLen()435 			size_t GetPublicKeyLen () const { return keyLen*2; }
GetSignatureLen()436 			size_t GetSignatureLen () const { return keyLen*2; }
437 
438 		private:
439 
440 			GOSTR3410ParamSet m_ParamSet;
441 			EC_POINT * m_PublicKey;
442 	};
443 
444 	template<typename Hash>
445 	class GOSTR3410Signer: public Signer
446 	{
447 		public:
448 
449 			enum { keyLen = Hash::hashLen };
450 
GOSTR3410Signer(GOSTR3410ParamSet paramSet,const uint8_t * signingPrivateKey)451 			GOSTR3410Signer (GOSTR3410ParamSet paramSet, const uint8_t * signingPrivateKey):
452 				m_ParamSet (paramSet)
453 			{
454 				m_PrivateKey = BN_bin2bn (signingPrivateKey, keyLen, nullptr);
455 			}
~GOSTR3410Signer()456 			~GOSTR3410Signer () { BN_free (m_PrivateKey); }
457 
Sign(const uint8_t * buf,int len,uint8_t * signature)458 			void Sign (const uint8_t * buf, int len, uint8_t * signature) const
459 			{
460 				uint8_t digest[Hash::hashLen];
461 				Hash::CalculateHash (buf, len, digest);
462 				BIGNUM * d = BN_bin2bn (digest, Hash::hashLen, nullptr);
463 				BIGNUM * r = BN_new (), * s = BN_new ();
464 				GetGOSTR3410Curve (m_ParamSet)->Sign (m_PrivateKey, d, r, s);
465 				bn2buf (r, signature, keyLen);
466 				bn2buf (s, signature + keyLen, keyLen);
467 				BN_free (d); BN_free (r); BN_free (s);
468 			}
469 
470 		private:
471 
472 			GOSTR3410ParamSet m_ParamSet;
473 			BIGNUM * m_PrivateKey;
474 	};
475 
CreateGOSTR3410RandomKeys(GOSTR3410ParamSet paramSet,uint8_t * signingPrivateKey,uint8_t * signingPublicKey)476 	inline void CreateGOSTR3410RandomKeys (GOSTR3410ParamSet paramSet, uint8_t * signingPrivateKey, uint8_t * signingPublicKey)
477 	{
478 		const auto& curve = GetGOSTR3410Curve (paramSet);
479 		auto keyLen = curve->GetKeyLen ();
480 		RAND_bytes (signingPrivateKey, keyLen);
481 		BIGNUM * priv = BN_bin2bn (signingPrivateKey, keyLen, nullptr);
482 
483 		auto pub = curve->MulP (priv);
484 		BN_free (priv);
485 		BIGNUM * x = BN_new (), * y = BN_new ();
486 		curve->GetXY (pub, x, y);
487 		EC_POINT_free (pub);
488 		bn2buf (x, signingPublicKey, keyLen);
489 		bn2buf (y, signingPublicKey + keyLen, keyLen);
490 		BN_free (x); BN_free (y);
491 	}
492 
493 	typedef GOSTR3410Verifier<GOSTR3411_256_Hash> GOSTR3410_256_Verifier;
494 	typedef GOSTR3410Signer<GOSTR3411_256_Hash> GOSTR3410_256_Signer;
495 	typedef GOSTR3410Verifier<GOSTR3411_512_Hash> GOSTR3410_512_Verifier;
496 	typedef GOSTR3410Signer<GOSTR3411_512_Hash> GOSTR3410_512_Signer;
497 
498 	// RedDSA
499 	typedef EDDSA25519Verifier RedDSA25519Verifier;
500 	class RedDSA25519Signer: public Signer
501 	{
502 		public:
503 
RedDSA25519Signer(const uint8_t * signingPrivateKey)504 			RedDSA25519Signer (const uint8_t * signingPrivateKey)
505 			{
506 				memcpy (m_PrivateKey, signingPrivateKey, EDDSA25519_PRIVATE_KEY_LENGTH);
507 				BN_CTX * ctx = BN_CTX_new ();
508 				auto publicKey = GetEd25519 ()->GeneratePublicKey (m_PrivateKey, ctx);
509 				GetEd25519 ()->EncodePublicKey (publicKey, m_PublicKeyEncoded, ctx);
510 				BN_CTX_free (ctx);
511 			}
~RedDSA25519Signer()512 			~RedDSA25519Signer () {};
513 
Sign(const uint8_t * buf,int len,uint8_t * signature)514 			void Sign (const uint8_t * buf, int len, uint8_t * signature) const
515 			{
516 				GetEd25519 ()->SignRedDSA (m_PrivateKey, m_PublicKeyEncoded, buf, len, signature);
517 			}
518 
GetPublicKey()519 			const uint8_t * GetPublicKey () const { return m_PublicKeyEncoded; }; // for keys creation
520 
521 		private:
522 
523 			uint8_t m_PrivateKey[EDDSA25519_PRIVATE_KEY_LENGTH];
524 			uint8_t m_PublicKeyEncoded[EDDSA25519_PUBLIC_KEY_LENGTH];
525 	};
526 
CreateRedDSA25519RandomKeys(uint8_t * signingPrivateKey,uint8_t * signingPublicKey)527 	inline void CreateRedDSA25519RandomKeys (uint8_t * signingPrivateKey, uint8_t * signingPublicKey)
528 	{
529 		GetEd25519 ()->CreateRedDSAPrivateKey (signingPrivateKey);
530 		RedDSA25519Signer signer (signingPrivateKey);
531 		memcpy (signingPublicKey, signer.GetPublicKey (), EDDSA25519_PUBLIC_KEY_LENGTH);
532 	}
533 }
534 }
535 
536 #endif
537