Signature.h
1 /* 2 * Copyright (c) 2013-2025, 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 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; 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 42 virtual ~Signer () {}; 43 virtual void Sign (const uint8_t * buf, int len, uint8_t * signature) const = 0; 44 }; 45 46 // DSA 47 const size_t DSA_PUBLIC_KEY_LENGTH = 128; 48 const size_t DSA_SIGNATURE_LENGTH = 40; 49 const size_t DSA_PRIVATE_KEY_LENGTH = DSA_SIGNATURE_LENGTH/2; 50 class DSAVerifier: public Verifier 51 { 52 public: 53 54 DSAVerifier (); 55 ~DSAVerifier (); 56 57 // implements Verifier 58 void SetPublicKey (const uint8_t * signingKey) override; 59 bool Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const override; 60 size_t GetPublicKeyLen () const override { return DSA_PUBLIC_KEY_LENGTH; }; 61 size_t GetSignatureLen () const override { return DSA_SIGNATURE_LENGTH; }; 62 63 private: 64 65 #if (OPENSSL_VERSION_NUMBER >= 0x030000000) // since 3.0.0 66 EVP_PKEY * m_PublicKey; 67 #else 68 DSA * m_PublicKey; 69 #endif 70 }; 71 72 class DSASigner: public Signer 73 { 74 public: 75 76 DSASigner (const uint8_t * signingPrivateKey, const uint8_t * signingPublicKey); 77 // openssl 1.1 always requires DSA public key even for signing 78 ~DSASigner (); 79 80 // implements Signer 81 void Sign (const uint8_t * buf, int len, uint8_t * signature) const override; 82 83 private: 84 85 #if (OPENSSL_VERSION_NUMBER >= 0x030000000) // since 3.0.0 86 EVP_PKEY * m_PrivateKey; 87 #else 88 DSA * m_PrivateKey; 89 #endif 90 }; 91 92 void CreateDSARandomKeys (uint8_t * signingPrivateKey, uint8_t * signingPublicKey); 93 94 // ECDSA 95 constexpr size_t ECDSAP256_KEY_LENGTH = 64; 96 constexpr size_t ECDSAP384_KEY_LENGTH = 96; 97 constexpr size_t ECDSAP521_KEY_LENGTH = 132; 98 99 #if (OPENSSL_VERSION_NUMBER >= 0x030000000) // since 3.0.0 100 class ECDSAVerifier: public Verifier 101 { 102 public: 103 104 ECDSAVerifier (int curve, size_t keyLen, const EVP_MD * hash); 105 ~ECDSAVerifier (); 106 107 void SetPublicKey (const uint8_t * signingKey); 108 bool Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const; 109 110 size_t GetPublicKeyLen () const { return m_KeyLen; }; 111 size_t GetSignatureLen () const { return m_KeyLen; }; // signature length = key length 112 113 private: 114 115 int m_Curve; 116 size_t m_KeyLen; 117 const EVP_MD * m_Hash; 118 EVP_PKEY * m_PublicKey; 119 }; 120 121 class ECDSASigner: public Signer 122 { 123 public: 124 125 ECDSASigner (int curve, size_t keyLen, const EVP_MD * hash, const uint8_t * signingPrivateKey); 126 ~ECDSASigner (); 127 128 void Sign (const uint8_t * buf, int len, uint8_t * signature) const; 129 130 private: 131 132 size_t m_KeyLen; 133 const EVP_MD * m_Hash; 134 EVP_PKEY * m_PrivateKey; 135 }; 136 137 void CreateECDSARandomKeys (int curve, size_t keyLen, uint8_t * signingPrivateKey, uint8_t * signingPublicKey); 138 139 // ECDSA_SHA256_P256 140 class ECDSAP256Verifier: public ECDSAVerifier 141 { 142 public: 143 144 ECDSAP256Verifier (): ECDSAVerifier (NID_X9_62_prime256v1, ECDSAP256_KEY_LENGTH, EVP_sha256()) {}; 145 }; 146 147 class ECDSAP256Signer: public ECDSASigner 148 { 149 public: 150 151 ECDSAP256Signer (const uint8_t * signingPrivateKey): 152 ECDSASigner (NID_X9_62_prime256v1, ECDSAP256_KEY_LENGTH, EVP_sha256(), signingPrivateKey) {}; 153 }; 154 155 inline void CreateECDSAP256RandomKeys (uint8_t * signingPrivateKey, uint8_t * signingPublicKey) 156 { 157 CreateECDSARandomKeys (NID_X9_62_prime256v1, ECDSAP256_KEY_LENGTH, signingPrivateKey, signingPublicKey); 158 } 159 160 // ECDSA_SHA384_P384 161 class ECDSAP384Verifier: public ECDSAVerifier 162 { 163 public: 164 165 ECDSAP384Verifier (): ECDSAVerifier (NID_secp384r1, ECDSAP384_KEY_LENGTH, EVP_sha384()) {}; 166 }; 167 168 class ECDSAP384Signer: public ECDSASigner 169 { 170 public: 171 172 ECDSAP384Signer (const uint8_t * signingPrivateKey): 173 ECDSASigner (NID_secp384r1, ECDSAP384_KEY_LENGTH, EVP_sha384(), signingPrivateKey) {}; 174 }; 175 176 inline void CreateECDSAP384RandomKeys (uint8_t * signingPrivateKey, uint8_t * signingPublicKey) 177 { 178 CreateECDSARandomKeys (NID_secp384r1, ECDSAP384_KEY_LENGTH, signingPrivateKey, signingPublicKey); 179 } 180 181 // ECDSA_SHA512_P521 182 class ECDSAP521Verifier: public ECDSAVerifier 183 { 184 public: 185 186 ECDSAP521Verifier (): ECDSAVerifier (NID_secp521r1, ECDSAP521_KEY_LENGTH, EVP_sha512()) {}; 187 }; 188 189 class ECDSAP521Signer: public ECDSASigner 190 { 191 public: 192 193 ECDSAP521Signer (const uint8_t * signingPrivateKey): 194 ECDSASigner (NID_secp521r1, ECDSAP521_KEY_LENGTH, EVP_sha512(), signingPrivateKey) {}; 195 }; 196 197 inline void CreateECDSAP521RandomKeys (uint8_t * signingPrivateKey, uint8_t * signingPublicKey) 198 { 199 CreateECDSARandomKeys (NID_secp521r1, ECDSAP521_KEY_LENGTH, signingPrivateKey, signingPublicKey); 200 } 201 202 #else 203 204 struct SHA256Hash 205 { 206 static void CalculateHash (const uint8_t * buf, size_t len, uint8_t * digest) 207 { 208 SHA256 (buf, len, digest); 209 } 210 211 enum { hashLen = 32 }; 212 }; 213 214 struct SHA384Hash 215 { 216 static void CalculateHash (const uint8_t * buf, size_t len, uint8_t * digest) 217 { 218 SHA384 (buf, len, digest); 219 } 220 221 enum { hashLen = 48 }; 222 }; 223 224 struct SHA512Hash 225 { 226 static void CalculateHash (const uint8_t * buf, size_t len, uint8_t * digest) 227 { 228 SHA512 (buf, len, digest); 229 } 230 231 enum { hashLen = 64 }; 232 }; 233 234 template<typename Hash, int curve, size_t keyLen> 235 class ECDSAVerifier: public Verifier 236 { 237 public: 238 239 ECDSAVerifier () 240 { 241 m_PublicKey = EC_KEY_new_by_curve_name (curve); 242 } 243 244 void SetPublicKey (const uint8_t * signingKey) 245 { 246 BIGNUM * x = BN_bin2bn (signingKey, keyLen/2, NULL); 247 BIGNUM * y = BN_bin2bn (signingKey + keyLen/2, keyLen/2, NULL); 248 EC_KEY_set_public_key_affine_coordinates (m_PublicKey, x, y); 249 BN_free (x); BN_free (y); 250 } 251 252 ~ECDSAVerifier () 253 { 254 EC_KEY_free (m_PublicKey); 255 } 256 257 bool Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const 258 { 259 uint8_t digest[Hash::hashLen]; 260 Hash::CalculateHash (buf, len, digest); 261 ECDSA_SIG * sig = ECDSA_SIG_new(); 262 auto r = BN_bin2bn (signature, GetSignatureLen ()/2, NULL); 263 auto s = BN_bin2bn (signature + GetSignatureLen ()/2, GetSignatureLen ()/2, NULL); 264 ECDSA_SIG_set0(sig, r, s); 265 // ECDSA verification 266 int ret = ECDSA_do_verify (digest, Hash::hashLen, sig, m_PublicKey) == 1; 267 ECDSA_SIG_free(sig); 268 return ret; 269 } 270 271 size_t GetPublicKeyLen () const { return keyLen; }; 272 size_t GetSignatureLen () const { return keyLen; }; // signature length = key length 273 274 275 private: 276 277 EC_KEY * m_PublicKey; 278 }; 279 280 template<typename Hash, int curve, size_t keyLen> 281 class ECDSASigner: public Signer 282 { 283 public: 284 285 ECDSASigner (const uint8_t * signingPrivateKey) 286 { 287 m_PrivateKey = EC_KEY_new_by_curve_name (curve); 288 EC_KEY_set_private_key (m_PrivateKey, BN_bin2bn (signingPrivateKey, keyLen/2, NULL)); 289 } 290 291 ~ECDSASigner () 292 { 293 EC_KEY_free (m_PrivateKey); 294 } 295 296 void Sign (const uint8_t * buf, int len, uint8_t * signature) const 297 { 298 uint8_t digest[Hash::hashLen]; 299 Hash::CalculateHash (buf, len, digest); 300 ECDSA_SIG * sig = ECDSA_do_sign (digest, Hash::hashLen, m_PrivateKey); 301 const BIGNUM * r, * s; 302 ECDSA_SIG_get0 (sig, &r, &s); 303 // signatureLen = keyLen 304 bn2buf (r, signature, keyLen/2); 305 bn2buf (s, signature + keyLen/2, keyLen/2); 306 ECDSA_SIG_free(sig); 307 } 308 309 private: 310 311 EC_KEY * m_PrivateKey; 312 }; 313 314 inline void CreateECDSARandomKeys (int curve, size_t keyLen, uint8_t * signingPrivateKey, uint8_t * signingPublicKey) 315 { 316 EC_KEY * signingKey = EC_KEY_new_by_curve_name (curve); 317 EC_KEY_generate_key (signingKey); 318 bn2buf (EC_KEY_get0_private_key (signingKey), signingPrivateKey, keyLen/2); 319 BIGNUM * x = BN_new(), * y = BN_new(); 320 EC_POINT_get_affine_coordinates_GFp (EC_KEY_get0_group(signingKey), 321 EC_KEY_get0_public_key (signingKey), x, y, NULL); 322 bn2buf (x, signingPublicKey, keyLen/2); 323 bn2buf (y, signingPublicKey + keyLen/2, keyLen/2); 324 BN_free (x); BN_free (y); 325 EC_KEY_free (signingKey); 326 } 327 328 // ECDSA_SHA256_P256 329 typedef ECDSAVerifier<SHA256Hash, NID_X9_62_prime256v1, ECDSAP256_KEY_LENGTH> ECDSAP256Verifier; 330 typedef ECDSASigner<SHA256Hash, NID_X9_62_prime256v1, ECDSAP256_KEY_LENGTH> ECDSAP256Signer; 331 332 inline void CreateECDSAP256RandomKeys (uint8_t * signingPrivateKey, uint8_t * signingPublicKey) 333 { 334 CreateECDSARandomKeys (NID_X9_62_prime256v1, ECDSAP256_KEY_LENGTH, signingPrivateKey, signingPublicKey); 335 } 336 337 // ECDSA_SHA384_P384 338 typedef ECDSAVerifier<SHA384Hash, NID_secp384r1, ECDSAP384_KEY_LENGTH> ECDSAP384Verifier; 339 typedef ECDSASigner<SHA384Hash, NID_secp384r1, ECDSAP384_KEY_LENGTH> ECDSAP384Signer; 340 341 inline void CreateECDSAP384RandomKeys (uint8_t * signingPrivateKey, uint8_t * signingPublicKey) 342 { 343 CreateECDSARandomKeys (NID_secp384r1, ECDSAP384_KEY_LENGTH, signingPrivateKey, signingPublicKey); 344 } 345 346 // ECDSA_SHA512_P521 347 typedef ECDSAVerifier<SHA512Hash, NID_secp521r1, ECDSAP521_KEY_LENGTH> ECDSAP521Verifier; 348 typedef ECDSASigner<SHA512Hash, NID_secp521r1, ECDSAP521_KEY_LENGTH> ECDSAP521Signer; 349 350 inline void CreateECDSAP521RandomKeys (uint8_t * signingPrivateKey, uint8_t * signingPublicKey) 351 { 352 CreateECDSARandomKeys (NID_secp521r1, ECDSAP521_KEY_LENGTH, signingPrivateKey, signingPublicKey); 353 } 354 355 #endif 356 357 // EdDSA 358 class EDDSA25519Verifier: public Verifier 359 { 360 public: 361 362 EDDSA25519Verifier (); 363 void SetPublicKey (const uint8_t * signingKey); 364 ~EDDSA25519Verifier (); 365 366 bool Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const; 367 368 size_t GetPublicKeyLen () const { return EDDSA25519_PUBLIC_KEY_LENGTH; }; 369 size_t GetSignatureLen () const { return EDDSA25519_SIGNATURE_LENGTH; }; 370 371 private: 372 373 EVP_PKEY * m_Pkey; 374 375 protected: 376 377 EVP_PKEY * GetPkey () const { return m_Pkey; }; 378 }; 379 380 #if (OPENSSL_VERSION_NUMBER >= 0x030000000) // since 3.0.0 381 class EDDSA25519phVerifier: public EDDSA25519Verifier 382 { 383 public: 384 385 bool Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const; 386 }; 387 #endif 388 389 class EDDSA25519SignerCompat: public Signer 390 { 391 public: 392 393 EDDSA25519SignerCompat (const uint8_t * signingPrivateKey, const uint8_t * signingPublicKey = nullptr); 394 // we pass signingPublicKey to check if it matches private key 395 ~EDDSA25519SignerCompat (); 396 397 void Sign (const uint8_t * buf, int len, uint8_t * signature) const; 398 const uint8_t * GetPublicKey () const { return m_PublicKeyEncoded; }; // for keys creation 399 400 private: 401 402 uint8_t m_ExpandedPrivateKey[64]; 403 uint8_t m_PublicKeyEncoded[EDDSA25519_PUBLIC_KEY_LENGTH]; 404 }; 405 406 class EDDSA25519Signer: public Signer 407 { 408 public: 409 410 EDDSA25519Signer (const uint8_t * signingPrivateKey, const uint8_t * signingPublicKey = nullptr); 411 // we pass signingPublicKey to check if it matches private key 412 ~EDDSA25519Signer (); 413 414 void Sign (const uint8_t * buf, int len, uint8_t * signature) const; 415 416 protected: 417 418 EVP_PKEY * GetPkey () const { return m_Pkey; }; 419 420 private: 421 422 EVP_PKEY * m_Pkey; 423 EDDSA25519SignerCompat * m_Fallback; 424 }; 425 426 #if (OPENSSL_VERSION_NUMBER >= 0x030000000) // since 3.0.0 427 class EDDSA25519phSigner: public EDDSA25519Signer 428 { 429 public: 430 431 EDDSA25519phSigner (const uint8_t * signingPrivateKey); 432 433 void Sign (const uint8_t * buf, int len, uint8_t * signature) const; 434 }; 435 436 #endif 437 438 inline void CreateEDDSA25519RandomKeys (uint8_t * signingPrivateKey, uint8_t * signingPublicKey) 439 { 440 EVP_PKEY *pkey = NULL; 441 EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_id (EVP_PKEY_ED25519, NULL); 442 EVP_PKEY_keygen_init (pctx); 443 EVP_PKEY_keygen (pctx, &pkey); 444 EVP_PKEY_CTX_free (pctx); 445 size_t len = EDDSA25519_PUBLIC_KEY_LENGTH; 446 EVP_PKEY_get_raw_public_key (pkey, signingPublicKey, &len); 447 len = EDDSA25519_PRIVATE_KEY_LENGTH; 448 EVP_PKEY_get_raw_private_key (pkey, signingPrivateKey, &len); 449 EVP_PKEY_free (pkey); 450 } 451 452 453 // ГОСТ Р 34.11 454 struct GOSTR3411_256_Hash 455 { 456 static void CalculateHash (const uint8_t * buf, size_t len, uint8_t * digest) 457 { 458 GOSTR3411_2012_256 (buf, len, digest); 459 } 460 461 enum { hashLen = 32 }; 462 }; 463 464 struct GOSTR3411_512_Hash 465 { 466 static void CalculateHash (const uint8_t * buf, size_t len, uint8_t * digest) 467 { 468 GOSTR3411_2012_512 (buf, len, digest); 469 } 470 471 enum { hashLen = 64 }; 472 }; 473 474 // ГОСТ Р 34.10 475 const size_t GOSTR3410_256_PUBLIC_KEY_LENGTH = 64; 476 const size_t GOSTR3410_512_PUBLIC_KEY_LENGTH = 128; 477 478 template<typename Hash> 479 class GOSTR3410Verifier: public Verifier 480 { 481 public: 482 483 enum { keyLen = Hash::hashLen }; 484 485 GOSTR3410Verifier (GOSTR3410ParamSet paramSet): 486 m_ParamSet (paramSet), m_PublicKey (nullptr) 487 { 488 } 489 490 void SetPublicKey (const uint8_t * signingKey) 491 { 492 BIGNUM * x = BN_bin2bn (signingKey, GetPublicKeyLen ()/2, NULL); 493 BIGNUM * y = BN_bin2bn (signingKey + GetPublicKeyLen ()/2, GetPublicKeyLen ()/2, NULL); 494 m_PublicKey = GetGOSTR3410Curve (m_ParamSet)->CreatePoint (x, y); 495 BN_free (x); BN_free (y); 496 } 497 ~GOSTR3410Verifier () 498 { 499 if (m_PublicKey) EC_POINT_free (m_PublicKey); 500 } 501 502 bool Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const 503 { 504 uint8_t digest[Hash::hashLen]; 505 Hash::CalculateHash (buf, len, digest); 506 BIGNUM * d = BN_bin2bn (digest, Hash::hashLen, nullptr); 507 BIGNUM * r = BN_bin2bn (signature, GetSignatureLen ()/2, NULL); 508 BIGNUM * s = BN_bin2bn (signature + GetSignatureLen ()/2, GetSignatureLen ()/2, NULL); 509 bool ret = GetGOSTR3410Curve (m_ParamSet)->Verify (m_PublicKey, d, r, s); 510 BN_free (d); BN_free (r); BN_free (s); 511 return ret; 512 } 513 514 size_t GetPublicKeyLen () const { return keyLen*2; } 515 size_t GetSignatureLen () const { return keyLen*2; } 516 517 private: 518 519 GOSTR3410ParamSet m_ParamSet; 520 EC_POINT * m_PublicKey; 521 }; 522 523 template<typename Hash> 524 class GOSTR3410Signer: public Signer 525 { 526 public: 527 528 enum { keyLen = Hash::hashLen }; 529 530 GOSTR3410Signer (GOSTR3410ParamSet paramSet, const uint8_t * signingPrivateKey): 531 m_ParamSet (paramSet) 532 { 533 m_PrivateKey = BN_bin2bn (signingPrivateKey, keyLen, nullptr); 534 } 535 ~GOSTR3410Signer () { BN_free (m_PrivateKey); } 536 537 void Sign (const uint8_t * buf, int len, uint8_t * signature) const 538 { 539 uint8_t digest[Hash::hashLen]; 540 Hash::CalculateHash (buf, len, digest); 541 BIGNUM * d = BN_bin2bn (digest, Hash::hashLen, nullptr); 542 BIGNUM * r = BN_new (), * s = BN_new (); 543 GetGOSTR3410Curve (m_ParamSet)->Sign (m_PrivateKey, d, r, s); 544 bn2buf (r, signature, keyLen); 545 bn2buf (s, signature + keyLen, keyLen); 546 BN_free (d); BN_free (r); BN_free (s); 547 } 548 549 private: 550 551 GOSTR3410ParamSet m_ParamSet; 552 BIGNUM * m_PrivateKey; 553 }; 554 555 inline void CreateGOSTR3410RandomKeys (GOSTR3410ParamSet paramSet, uint8_t * signingPrivateKey, uint8_t * signingPublicKey) 556 { 557 const auto& curve = GetGOSTR3410Curve (paramSet); 558 auto keyLen = curve->GetKeyLen (); 559 RAND_bytes (signingPrivateKey, keyLen); 560 BIGNUM * priv = BN_bin2bn (signingPrivateKey, keyLen, nullptr); 561 562 auto pub = curve->MulP (priv); 563 BN_free (priv); 564 BIGNUM * x = BN_new (), * y = BN_new (); 565 curve->GetXY (pub, x, y); 566 EC_POINT_free (pub); 567 bn2buf (x, signingPublicKey, keyLen); 568 bn2buf (y, signingPublicKey + keyLen, keyLen); 569 BN_free (x); BN_free (y); 570 } 571 572 typedef GOSTR3410Verifier<GOSTR3411_256_Hash> GOSTR3410_256_Verifier; 573 typedef GOSTR3410Signer<GOSTR3411_256_Hash> GOSTR3410_256_Signer; 574 typedef GOSTR3410Verifier<GOSTR3411_512_Hash> GOSTR3410_512_Verifier; 575 typedef GOSTR3410Signer<GOSTR3411_512_Hash> GOSTR3410_512_Signer; 576 577 // RedDSA 578 typedef EDDSA25519Verifier RedDSA25519Verifier; 579 class RedDSA25519Signer: public Signer 580 { 581 public: 582 583 RedDSA25519Signer (const uint8_t * signingPrivateKey) 584 { 585 memcpy (m_PrivateKey, signingPrivateKey, EDDSA25519_PRIVATE_KEY_LENGTH); 586 BN_CTX * ctx = BN_CTX_new (); 587 auto publicKey = GetEd25519 ()->GeneratePublicKey (m_PrivateKey, ctx); 588 GetEd25519 ()->EncodePublicKey (publicKey, m_PublicKeyEncoded, ctx); 589 BN_CTX_free (ctx); 590 } 591 ~RedDSA25519Signer () {}; 592 593 void Sign (const uint8_t * buf, int len, uint8_t * signature) const 594 { 595 GetEd25519 ()->SignRedDSA (m_PrivateKey, m_PublicKeyEncoded, buf, len, signature); 596 } 597 598 const uint8_t * GetPublicKey () const { return m_PublicKeyEncoded; }; // for keys creation 599 600 private: 601 602 uint8_t m_PrivateKey[EDDSA25519_PRIVATE_KEY_LENGTH]; 603 uint8_t m_PublicKeyEncoded[EDDSA25519_PUBLIC_KEY_LENGTH]; 604 }; 605 606 inline void CreateRedDSA25519RandomKeys (uint8_t * signingPrivateKey, uint8_t * signingPublicKey) 607 { 608 GetEd25519 ()->CreateRedDSAPrivateKey (signingPrivateKey); 609 RedDSA25519Signer signer (signingPrivateKey); 610 memcpy (signingPublicKey, signer.GetPublicKey (), EDDSA25519_PUBLIC_KEY_LENGTH); 611 } 612 613 #if OPENSSL_PQ 614 #include <openssl/core_names.h> 615 616 // Post-Quantum 617 const size_t MLDSA44_PUBLIC_KEY_LENGTH = 1312; 618 const size_t MLDSA44_SIGNATURE_LENGTH = 2420; 619 const size_t MLDSA44_PRIVATE_KEY_LENGTH = 2560; 620 class MLDSA44Verifier: public Verifier 621 { 622 public: 623 624 MLDSA44Verifier (); 625 void SetPublicKey (const uint8_t * signingKey); 626 ~MLDSA44Verifier (); 627 628 bool Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const; 629 630 size_t GetPublicKeyLen () const { return MLDSA44_PUBLIC_KEY_LENGTH; }; 631 size_t GetSignatureLen () const { return MLDSA44_SIGNATURE_LENGTH; }; 632 size_t GetPrivateKeyLen () const { return MLDSA44_PRIVATE_KEY_LENGTH; }; 633 634 private: 635 636 EVP_PKEY * m_Pkey; 637 }; 638 639 class MLDSA44Signer: public Signer 640 { 641 public: 642 643 MLDSA44Signer (const uint8_t * signingPrivateKey); 644 ~MLDSA44Signer (); 645 646 void Sign (const uint8_t * buf, int len, uint8_t * signature) const; 647 648 private: 649 650 EVP_PKEY * m_Pkey; 651 }; 652 653 inline void CreateMLDSA44RandomKeys (uint8_t * signingPrivateKey, uint8_t * signingPublicKey) 654 { 655 EVP_PKEY * pkey = EVP_PKEY_Q_keygen (NULL, NULL, "ML-DSA-44"); 656 size_t len = MLDSA44_PUBLIC_KEY_LENGTH; 657 EVP_PKEY_get_octet_string_param (pkey, OSSL_PKEY_PARAM_PUB_KEY, signingPublicKey, MLDSA44_PUBLIC_KEY_LENGTH, &len); 658 len = MLDSA44_PRIVATE_KEY_LENGTH; 659 EVP_PKEY_get_octet_string_param (pkey, OSSL_PKEY_PARAM_PRIV_KEY, signingPrivateKey, MLDSA44_PRIVATE_KEY_LENGTH, &len); 660 EVP_PKEY_free (pkey); 661 } 662 #endif 663 } 664 } 665 666 #endif