react-native-quick-crypto 1.0.0-beta.12 → 1.0.0-beta.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (115) hide show
  1. package/README.md +1 -1
  2. package/android/CMakeLists.txt +8 -2
  3. package/android/src/main/java/com/margelo/nitro/quickcrypto/QuickCryptoPackage.java +0 -2
  4. package/cpp/cipher/CCMCipher.cpp +199 -0
  5. package/cpp/cipher/CCMCipher.hpp +26 -0
  6. package/cpp/cipher/HybridCipher.cpp +324 -0
  7. package/cpp/cipher/HybridCipher.hpp +69 -0
  8. package/cpp/cipher/HybridCipherFactory.hpp +59 -0
  9. package/cpp/cipher/OCBCipher.cpp +55 -0
  10. package/cpp/cipher/OCBCipher.hpp +19 -0
  11. package/cpp/ed25519/HybridEdKeyPair.cpp +34 -91
  12. package/cpp/ed25519/HybridEdKeyPair.hpp +24 -54
  13. package/cpp/hash/HybridHash.cpp +30 -60
  14. package/cpp/hash/HybridHash.hpp +11 -27
  15. package/cpp/hmac/HybridHmac.cpp +95 -0
  16. package/cpp/hmac/HybridHmac.hpp +31 -0
  17. package/cpp/pbkdf2/HybridPbkdf2.cpp +34 -55
  18. package/cpp/pbkdf2/HybridPbkdf2.hpp +5 -16
  19. package/cpp/random/HybridRandom.cpp +5 -16
  20. package/cpp/random/HybridRandom.hpp +5 -6
  21. package/cpp/utils/Utils.hpp +1 -2
  22. package/lib/commonjs/cipher.js +157 -0
  23. package/lib/commonjs/cipher.js.map +1 -0
  24. package/lib/commonjs/hash.js +41 -18
  25. package/lib/commonjs/hash.js.map +1 -1
  26. package/lib/commonjs/hmac.js +109 -0
  27. package/lib/commonjs/hmac.js.map +1 -0
  28. package/lib/commonjs/index.js +31 -25
  29. package/lib/commonjs/index.js.map +1 -1
  30. package/lib/commonjs/pbkdf2.js.map +1 -1
  31. package/lib/commonjs/specs/cipher.nitro.js +6 -0
  32. package/lib/commonjs/specs/cipher.nitro.js.map +1 -0
  33. package/lib/commonjs/specs/hmac.nitro.js +6 -0
  34. package/lib/commonjs/specs/hmac.nitro.js.map +1 -0
  35. package/lib/commonjs/utils/cipher.js +64 -0
  36. package/lib/commonjs/utils/cipher.js.map +1 -0
  37. package/lib/commonjs/utils/types.js +3 -1
  38. package/lib/commonjs/utils/types.js.map +1 -1
  39. package/lib/module/cipher.js +150 -0
  40. package/lib/module/cipher.js.map +1 -0
  41. package/lib/module/hash.js +41 -18
  42. package/lib/module/hash.js.map +1 -1
  43. package/lib/module/hmac.js +104 -0
  44. package/lib/module/hmac.js.map +1 -0
  45. package/lib/module/index.js +9 -23
  46. package/lib/module/index.js.map +1 -1
  47. package/lib/module/pbkdf2.js.map +1 -1
  48. package/lib/module/specs/cipher.nitro.js +4 -0
  49. package/lib/module/specs/cipher.nitro.js.map +1 -0
  50. package/lib/module/specs/hmac.nitro.js +4 -0
  51. package/lib/module/specs/hmac.nitro.js.map +1 -0
  52. package/lib/module/utils/cipher.js +56 -0
  53. package/lib/module/utils/cipher.js.map +1 -0
  54. package/lib/module/utils/types.js +4 -0
  55. package/lib/module/utils/types.js.map +1 -1
  56. package/lib/tsconfig.tsbuildinfo +1 -1
  57. package/lib/typescript/cipher.d.ts +52 -0
  58. package/lib/typescript/cipher.d.ts.map +1 -0
  59. package/lib/typescript/hash.d.ts +23 -1
  60. package/lib/typescript/hash.d.ts.map +1 -1
  61. package/lib/typescript/hmac.d.ts +66 -0
  62. package/lib/typescript/hmac.d.ts.map +1 -0
  63. package/lib/typescript/index.d.ts +17 -12
  64. package/lib/typescript/index.d.ts.map +1 -1
  65. package/lib/typescript/keys/utils.d.ts.map +1 -1
  66. package/lib/typescript/pbkdf2.d.ts +1 -1
  67. package/lib/typescript/pbkdf2.d.ts.map +1 -1
  68. package/lib/typescript/specs/cipher.nitro.d.ts +29 -0
  69. package/lib/typescript/specs/cipher.nitro.d.ts.map +1 -0
  70. package/lib/typescript/specs/hmac.nitro.d.ts +10 -0
  71. package/lib/typescript/specs/hmac.nitro.d.ts.map +1 -0
  72. package/lib/typescript/utils/cipher.d.ts +7 -0
  73. package/lib/typescript/utils/cipher.d.ts.map +1 -0
  74. package/lib/typescript/utils/conversion.d.ts.map +1 -1
  75. package/lib/typescript/utils/types.d.ts +6 -1
  76. package/lib/typescript/utils/types.d.ts.map +1 -1
  77. package/nitrogen/generated/.gitattributes +1 -0
  78. package/nitrogen/generated/android/QuickCrypto+autolinking.cmake +19 -0
  79. package/nitrogen/generated/android/QuickCryptoOnLoad.cpp +35 -5
  80. package/nitrogen/generated/android/kotlin/com/margelo/nitro/crypto/QuickCryptoOnLoad.kt +35 -0
  81. package/nitrogen/generated/ios/QuickCrypto+autolinking.rb +2 -0
  82. package/nitrogen/generated/ios/QuickCrypto-Swift-Cxx-Umbrella.hpp +0 -1
  83. package/nitrogen/generated/ios/QuickCryptoAutolinking.mm +35 -5
  84. package/nitrogen/generated/shared/c++/CFRGKeyPairType.hpp +1 -1
  85. package/nitrogen/generated/shared/c++/CipherArgs.hpp +88 -0
  86. package/nitrogen/generated/shared/c++/HybridCipherFactorySpec.cpp +21 -0
  87. package/nitrogen/generated/shared/c++/HybridCipherFactorySpec.hpp +67 -0
  88. package/nitrogen/generated/shared/c++/HybridCipherSpec.cpp +28 -0
  89. package/nitrogen/generated/shared/c++/HybridCipherSpec.hpp +76 -0
  90. package/nitrogen/generated/shared/c++/HybridEdKeyPairSpec.hpp +1 -1
  91. package/nitrogen/generated/shared/c++/HybridHashSpec.hpp +1 -1
  92. package/nitrogen/generated/shared/c++/HybridHmacSpec.cpp +23 -0
  93. package/nitrogen/generated/shared/c++/HybridHmacSpec.hpp +66 -0
  94. package/nitrogen/generated/shared/c++/HybridKeyObjectHandleSpec.hpp +1 -1
  95. package/nitrogen/generated/shared/c++/HybridPbkdf2Spec.hpp +1 -1
  96. package/nitrogen/generated/shared/c++/HybridRandomSpec.hpp +1 -1
  97. package/nitrogen/generated/shared/c++/JWK.hpp +2 -1
  98. package/nitrogen/generated/shared/c++/JWKkty.hpp +1 -1
  99. package/nitrogen/generated/shared/c++/JWKuse.hpp +1 -1
  100. package/nitrogen/generated/shared/c++/KFormatType.hpp +1 -1
  101. package/nitrogen/generated/shared/c++/KeyDetail.hpp +2 -1
  102. package/nitrogen/generated/shared/c++/KeyEncoding.hpp +1 -1
  103. package/nitrogen/generated/shared/c++/KeyType.hpp +1 -1
  104. package/nitrogen/generated/shared/c++/KeyUsage.hpp +1 -1
  105. package/nitrogen/generated/shared/c++/NamedCurve.hpp +1 -1
  106. package/package.json +3 -13
  107. package/src/cipher.ts +303 -0
  108. package/src/hash.ts +51 -15
  109. package/src/hmac.ts +135 -0
  110. package/src/index.ts +9 -23
  111. package/src/pbkdf2.ts +1 -1
  112. package/src/specs/cipher.nitro.ts +25 -0
  113. package/src/specs/hmac.nitro.ts +7 -0
  114. package/src/utils/cipher.ts +60 -0
  115. package/src/utils/types.ts +27 -0
@@ -11,42 +11,26 @@ namespace margelo::nitro::crypto {
11
11
 
12
12
  using namespace facebook;
13
13
 
14
- class HybridHash : public HybridHashSpec
15
- {
16
- public:
17
- HybridHash()
18
- : HybridObject(TAG)
19
- {
20
- }
21
- HybridHash(EVP_MD_CTX* ctx,
22
- const EVP_MD* md,
23
- const std::string& algorithm,
24
- const std::optional<double> outputLength)
25
- : HybridObject(TAG)
26
- , ctx(ctx)
27
- , md(md)
28
- , algorithm(algorithm)
29
- , outputLength(outputLength)
30
- {
31
- }
14
+ class HybridHash : public HybridHashSpec {
15
+ public:
16
+ HybridHash() : HybridObject(TAG) {}
17
+ HybridHash(EVP_MD_CTX* ctx, const EVP_MD* md, const std::string& algorithm, const std::optional<double> outputLength)
18
+ : HybridObject(TAG), ctx(ctx), md(md), algorithm(algorithm), outputLength(outputLength) {}
32
19
  ~HybridHash();
33
20
 
34
- public:
21
+ public:
35
22
  // Methods
36
- void createHash(const std::string& algorithm,
37
- const std::optional<double> outputLength) override;
23
+ void createHash(const std::string& algorithm, const std::optional<double> outputLength) override;
38
24
  void update(const std::shared_ptr<ArrayBuffer>& data) override;
39
- std::shared_ptr<ArrayBuffer> digest(
40
- const std::optional<std::string>& encoding = std::nullopt) override;
41
- std::shared_ptr<margelo::nitro::crypto::HybridHashSpec> copy(
42
- const std::optional<double> outputLength) override;
25
+ std::shared_ptr<ArrayBuffer> digest(const std::optional<std::string>& encoding = std::nullopt) override;
26
+ std::shared_ptr<margelo::nitro::crypto::HybridHashSpec> copy(const std::optional<double> outputLength) override;
43
27
  std::vector<std::string> getSupportedHashAlgorithms() override;
44
28
 
45
- private:
29
+ private:
46
30
  // Methods
47
31
  void setParams();
48
32
 
49
- private:
33
+ private:
50
34
  // Properties
51
35
  EVP_MD_CTX* ctx = nullptr;
52
36
  const EVP_MD* md = nullptr;
@@ -0,0 +1,95 @@
1
+ #include <NitroModules/ArrayBuffer.hpp>
2
+ #include <memory>
3
+ #include <openssl/err.h>
4
+ #include <openssl/evp.h>
5
+ #include <optional>
6
+ #include <string>
7
+ #include <vector>
8
+
9
+ #include "HybridHmac.hpp"
10
+
11
+ namespace margelo::nitro::crypto {
12
+
13
+ HybridHmac::~HybridHmac() {
14
+ if (ctx) {
15
+ EVP_MAC_CTX_free(ctx);
16
+ ctx = nullptr;
17
+ }
18
+ }
19
+
20
+ void HybridHmac::createHmac(const std::string& hmacAlgorithm, const std::shared_ptr<ArrayBuffer>& secretKey) {
21
+ algorithm = hmacAlgorithm;
22
+
23
+ // Create and use EVP_MAC locally
24
+ EVP_MAC* mac = EVP_MAC_fetch(nullptr, "HMAC", nullptr);
25
+ if (!mac) {
26
+ throw std::runtime_error("Failed to fetch HMAC implementation: " + std::to_string(ERR_get_error()));
27
+ }
28
+
29
+ // Create HMAC context
30
+ ctx = EVP_MAC_CTX_new(mac);
31
+ EVP_MAC_free(mac); // Free immediately after creating the context
32
+ if (!ctx) {
33
+ throw std::runtime_error("Failed to create HMAC context: " + std::to_string(ERR_get_error()));
34
+ }
35
+
36
+ // Validate algorithm
37
+ const EVP_MD* md = EVP_get_digestbyname(algorithm.c_str());
38
+ if (!md) {
39
+ throw std::runtime_error("Unknown HMAC algorithm: " + algorithm);
40
+ }
41
+
42
+ // Set up parameters for HMAC
43
+ OSSL_PARAM params[2];
44
+ params[0] = OSSL_PARAM_construct_utf8_string("digest", const_cast<char*>(algorithm.c_str()), 0);
45
+ params[1] = OSSL_PARAM_construct_end();
46
+
47
+ const uint8_t* keyData = reinterpret_cast<const uint8_t*>(secretKey->data());
48
+ size_t keySize = secretKey->size();
49
+
50
+ // Handle empty key case by providing a dummy key
51
+ static const uint8_t dummyKey = 0;
52
+ if (keySize == 0) {
53
+ keyData = &dummyKey;
54
+ keySize = 1;
55
+ }
56
+
57
+ // Initialize HMAC
58
+ if (EVP_MAC_init(ctx, keyData, keySize, params) != 1) {
59
+ throw std::runtime_error("Failed to initialize HMAC: " + std::to_string(ERR_get_error()));
60
+ }
61
+ }
62
+
63
+ void HybridHmac::update(const std::shared_ptr<ArrayBuffer>& data) {
64
+ if (!ctx) {
65
+ throw std::runtime_error("HMAC context not initialized");
66
+ }
67
+
68
+ // Update HMAC with new data
69
+ if (EVP_MAC_update(ctx, reinterpret_cast<const uint8_t*>(data->data()), data->size()) != 1) {
70
+ throw std::runtime_error("Failed to update HMAC: " + std::to_string(ERR_get_error()));
71
+ }
72
+ }
73
+
74
+ std::shared_ptr<ArrayBuffer> HybridHmac::digest() {
75
+ if (!ctx) {
76
+ throw std::runtime_error("HMAC context not initialized");
77
+ }
78
+
79
+ // Determine the maximum possible size of the HMAC output
80
+ const EVP_MD* md = EVP_get_digestbyname(algorithm.c_str());
81
+ const size_t hmacLength = EVP_MD_get_size(md);
82
+
83
+ // Allocate buffer with the exact required size
84
+ uint8_t* hmacBuffer = new uint8_t[hmacLength];
85
+
86
+ // Finalize the HMAC computation directly into the final buffer
87
+ if (EVP_MAC_final(ctx, hmacBuffer, nullptr, hmacLength) != 1) {
88
+ delete[] hmacBuffer;
89
+ throw std::runtime_error("Failed to finalize HMAC digest: " + std::to_string(ERR_get_error()));
90
+ }
91
+
92
+ return std::make_shared<NativeArrayBuffer>(hmacBuffer, hmacLength, [=]() { delete[] hmacBuffer; });
93
+ }
94
+
95
+ } // namespace margelo::nitro::crypto
@@ -0,0 +1,31 @@
1
+ #include <NitroModules/ArrayBuffer.hpp>
2
+ #include <memory>
3
+ #include <openssl/evp.h>
4
+ #include <optional>
5
+ #include <string>
6
+ #include <vector>
7
+
8
+ #include "HybridHmacSpec.hpp"
9
+
10
+ namespace margelo::nitro::crypto {
11
+
12
+ using namespace facebook;
13
+
14
+ class HybridHmac : public HybridHmacSpec {
15
+ public:
16
+ HybridHmac() : HybridObject(TAG) {}
17
+ ~HybridHmac();
18
+
19
+ public:
20
+ // Methods
21
+ void createHmac(const std::string& algorithm, const std::shared_ptr<ArrayBuffer>& key) override;
22
+ void update(const std::shared_ptr<ArrayBuffer>& data) override;
23
+ std::shared_ptr<ArrayBuffer> digest() override;
24
+
25
+ private:
26
+ // Properties
27
+ EVP_MAC_CTX* ctx = nullptr;
28
+ std::string algorithm = "";
29
+ };
30
+
31
+ } // namespace margelo::nitro::crypto
@@ -3,70 +3,49 @@
3
3
 
4
4
  namespace margelo::nitro::crypto {
5
5
 
6
- std::shared_ptr<Promise<std::shared_ptr<ArrayBuffer>>>
7
- HybridPbkdf2::pbkdf2(
8
- const std::shared_ptr<ArrayBuffer>& password,
9
- const std::shared_ptr<ArrayBuffer>& salt,
10
- double iterations,
11
- double keylen,
12
- const std::string& digest
13
- ) {
6
+ std::shared_ptr<Promise<std::shared_ptr<ArrayBuffer>>> HybridPbkdf2::pbkdf2(const std::shared_ptr<ArrayBuffer>& password,
7
+ const std::shared_ptr<ArrayBuffer>& salt, double iterations,
8
+ double keylen, const std::string& digest) {
14
9
  // get owned NativeArrayBuffers before passing to sync function
15
10
  auto nativePassword = ToNativeArrayBuffer(password);
16
11
  auto nativeSalt = ToNativeArrayBuffer(salt);
17
12
 
18
- return Promise<std::shared_ptr<ArrayBuffer>>::async(
19
- [this, nativePassword, nativeSalt, iterations, keylen, digest]() {
20
- return this->pbkdf2Sync(nativePassword, nativeSalt, iterations, keylen, digest);
21
- }
22
- );
13
+ return Promise<std::shared_ptr<ArrayBuffer>>::async([this, nativePassword, nativeSalt, iterations, keylen, digest]() {
14
+ return this->pbkdf2Sync(nativePassword, nativeSalt, iterations, keylen, digest);
15
+ });
23
16
  }
24
17
 
25
- std::shared_ptr<ArrayBuffer>
26
- HybridPbkdf2::pbkdf2Sync(
27
- const std::shared_ptr<ArrayBuffer>& password,
28
- const std::shared_ptr<ArrayBuffer>& salt,
29
- double iterations,
30
- double keylen,
31
- const std::string& digest
32
- ) {
33
- size_t bufferSize = static_cast<size_t>(keylen);
34
- uint8_t* data = new uint8_t[bufferSize];
35
- auto result = std::make_shared<NativeArrayBuffer>(data, bufferSize, [=]() { delete[] data; });
18
+ std::shared_ptr<ArrayBuffer> HybridPbkdf2::pbkdf2Sync(const std::shared_ptr<ArrayBuffer>& password,
19
+ const std::shared_ptr<ArrayBuffer>& salt, double iterations, double keylen,
20
+ const std::string& digest) {
21
+ size_t bufferSize = static_cast<size_t>(keylen);
22
+ uint8_t* data = new uint8_t[bufferSize];
23
+ auto result = std::make_shared<NativeArrayBuffer>(data, bufferSize, [=]() { delete[] data; });
36
24
 
37
- // use fastpbkdf2 when possible
38
- if (digest == "sha1") {
39
- fastpbkdf2_hmac_sha1(password.get()->data(), password.get()->size(),
40
- salt.get()->data(), salt.get()->size(),
41
- static_cast<uint32_t>(iterations),
42
- result.get()->data(), result.get()->size());
43
- } else if (digest == "sha256") {
44
- fastpbkdf2_hmac_sha256(password.get()->data(), password.get()->size(),
45
- salt.get()->data(), salt.get()->size(),
46
- static_cast<uint32_t>(iterations),
47
- result.get()->data(), result.get()->size());
48
- } else if (digest == "sha512") {
49
- fastpbkdf2_hmac_sha512(password.get()->data(), password.get()->size(),
50
- salt.get()->data(), salt.get()->size(),
51
- static_cast<uint32_t>(iterations),
52
- result.get()->data(), result.get()->size());
53
- } else {
54
- // fallback to OpenSSL
55
- auto *digestByName = EVP_get_digestbyname(digest.c_str());
56
- if (digestByName == nullptr) {
57
- throw std::runtime_error("Invalid hash-algorithm: " + digest);
58
- }
59
- char *passAsCharA = reinterpret_cast<char *>(password.get()->data());
60
- const unsigned char *saltAsCharA =
61
- reinterpret_cast<const unsigned char *>(salt.get()->data());
62
- unsigned char *resultAsCharA =
63
- reinterpret_cast<unsigned char *>(result.get()->data());
64
- PKCS5_PBKDF2_HMAC(passAsCharA, password.get()->size(), saltAsCharA,
65
- salt.get()->size(), static_cast<uint32_t>(iterations),
66
- digestByName, result.get()->size(), resultAsCharA);
25
+ // use fastpbkdf2 when possible
26
+ if (digest == "sha1") {
27
+ fastpbkdf2_hmac_sha1(password.get()->data(), password.get()->size(), salt.get()->data(), salt.get()->size(),
28
+ static_cast<uint32_t>(iterations), result.get()->data(), result.get()->size());
29
+ } else if (digest == "sha256") {
30
+ fastpbkdf2_hmac_sha256(password.get()->data(), password.get()->size(), salt.get()->data(), salt.get()->size(),
31
+ static_cast<uint32_t>(iterations), result.get()->data(), result.get()->size());
32
+ } else if (digest == "sha512") {
33
+ fastpbkdf2_hmac_sha512(password.get()->data(), password.get()->size(), salt.get()->data(), salt.get()->size(),
34
+ static_cast<uint32_t>(iterations), result.get()->data(), result.get()->size());
35
+ } else {
36
+ // fallback to OpenSSL
37
+ auto* digestByName = EVP_get_digestbyname(digest.c_str());
38
+ if (digestByName == nullptr) {
39
+ throw std::runtime_error("Invalid hash-algorithm: " + digest);
67
40
  }
41
+ char* passAsCharA = reinterpret_cast<char*>(password.get()->data());
42
+ const unsigned char* saltAsCharA = reinterpret_cast<const unsigned char*>(salt.get()->data());
43
+ unsigned char* resultAsCharA = reinterpret_cast<unsigned char*>(result.get()->data());
44
+ PKCS5_PBKDF2_HMAC(passAsCharA, password.get()->size(), saltAsCharA, salt.get()->size(), static_cast<uint32_t>(iterations), digestByName,
45
+ result.get()->size(), resultAsCharA);
46
+ }
68
47
 
69
- return result;
48
+ return result;
70
49
  }
71
50
 
72
51
  } // namespace margelo::nitro::crypto
@@ -13,23 +13,12 @@ class HybridPbkdf2 : public HybridPbkdf2Spec {
13
13
 
14
14
  public:
15
15
  // Methods
16
- std::shared_ptr<Promise<std::shared_ptr<ArrayBuffer>>>
17
- pbkdf2(
18
- const std::shared_ptr<ArrayBuffer>& password,
19
- const std::shared_ptr<ArrayBuffer>& salt,
20
- double iterations,
21
- double keylen,
22
- const std::string& digest
23
- ) override;
16
+ std::shared_ptr<Promise<std::shared_ptr<ArrayBuffer>>> pbkdf2(const std::shared_ptr<ArrayBuffer>& password,
17
+ const std::shared_ptr<ArrayBuffer>& salt, double iterations, double keylen,
18
+ const std::string& digest) override;
24
19
 
25
- std::shared_ptr<ArrayBuffer>
26
- pbkdf2Sync(
27
- const std::shared_ptr<ArrayBuffer>& password,
28
- const std::shared_ptr<ArrayBuffer>& salt,
29
- double iterations,
30
- double keylen,
31
- const std::string& digest
32
- ) override;
20
+ std::shared_ptr<ArrayBuffer> pbkdf2Sync(const std::shared_ptr<ArrayBuffer>& password, const std::shared_ptr<ArrayBuffer>& salt,
21
+ double iterations, double keylen, const std::string& digest) override;
33
22
  };
34
23
 
35
24
  } // namespace margelo::nitro::crypto
@@ -4,7 +4,6 @@
4
4
  #include "HybridRandom.hpp"
5
5
  #include "Utils.hpp"
6
6
 
7
-
8
7
  size_t checkSize(double size) {
9
8
  if (!CheckIsUint32(size)) {
10
9
  throw std::runtime_error("size must be uint32");
@@ -25,33 +24,23 @@ size_t checkOffset(double size, double offset) {
25
24
  return static_cast<size_t>(offset);
26
25
  }
27
26
 
28
-
29
27
  namespace margelo::nitro::crypto {
30
28
 
31
- std::shared_ptr<Promise<std::shared_ptr<ArrayBuffer>>>
32
- HybridRandom::randomFill(const std::shared_ptr<ArrayBuffer>& buffer,
33
- double dOffset,
34
- double dSize) {
29
+ std::shared_ptr<Promise<std::shared_ptr<ArrayBuffer>>> HybridRandom::randomFill(const std::shared_ptr<ArrayBuffer>& buffer, double dOffset,
30
+ double dSize) {
35
31
  // get owned NativeArrayBuffer before passing to sync function
36
32
  auto nativeBuffer = ToNativeArrayBuffer(buffer);
37
33
 
38
34
  return Promise<std::shared_ptr<ArrayBuffer>>::async(
39
- [this, nativeBuffer, dOffset, dSize]() {
40
- return this->randomFillSync(nativeBuffer, dOffset, dSize);
41
- }
42
- );
35
+ [this, nativeBuffer, dOffset, dSize]() { return this->randomFillSync(nativeBuffer, dOffset, dSize); });
43
36
  };
44
37
 
45
- std::shared_ptr<ArrayBuffer>
46
- HybridRandom::randomFillSync(const std::shared_ptr<ArrayBuffer>& buffer,
47
- double dOffset,
48
- double dSize) {
38
+ std::shared_ptr<ArrayBuffer> HybridRandom::randomFillSync(const std::shared_ptr<ArrayBuffer>& buffer, double dOffset, double dSize) {
49
39
  size_t size = checkSize(dSize);
50
40
  size_t offset = checkOffset(dSize, dOffset);
51
41
  uint8_t* data = buffer.get()->data();
52
42
  if (RAND_bytes(data + offset, (int)size) != 1) {
53
- throw std::runtime_error("error calling RAND_bytes" +
54
- std::to_string(ERR_get_error()));
43
+ throw std::runtime_error("error calling RAND_bytes: " + std::to_string(ERR_get_error()));
55
44
  }
56
45
  return buffer;
57
46
  };
@@ -1,7 +1,7 @@
1
1
  #include <cmath>
2
2
  #include <future>
3
- #include <memory>
4
3
  #include <iostream>
4
+ #include <memory>
5
5
 
6
6
  #include "HybridRandomSpec.hpp"
7
7
 
@@ -15,17 +15,16 @@ class HybridRandom : public HybridRandomSpec {
15
15
 
16
16
  public:
17
17
  // Methods
18
- std::shared_ptr<Promise<std::shared_ptr<ArrayBuffer>>>
19
- randomFill(const std::shared_ptr<ArrayBuffer>& buffer, double dOffset, double dSize) override;
18
+ std::shared_ptr<Promise<std::shared_ptr<ArrayBuffer>>> randomFill(const std::shared_ptr<ArrayBuffer>& buffer, double dOffset,
19
+ double dSize) override;
20
20
 
21
- std::shared_ptr<ArrayBuffer>
22
- randomFillSync(const std::shared_ptr<ArrayBuffer>& buffer, double dOffset, double dSize) override;
21
+ std::shared_ptr<ArrayBuffer> randomFillSync(const std::shared_ptr<ArrayBuffer>& buffer, double dOffset, double dSize) override;
23
22
  };
24
23
 
25
24
  inline void printData(std::string name, uint8_t* data, size_t size) {
26
25
  std::cout << "data - " << name << std::endl;
27
26
  for (size_t i = 0; i < size; i++) {
28
- printf("%u ", data[i]);
27
+ printf("%u ", data[i]);
29
28
  }
30
29
  printf("\n");
31
30
  }
@@ -3,8 +3,7 @@
3
3
  #include <NitroModules/ArrayBuffer.hpp>
4
4
 
5
5
  // copy a JSArrayBuffer that we do not own into a NativeArrayBuffer that we do own
6
- inline std::shared_ptr<margelo::nitro::NativeArrayBuffer>
7
- ToNativeArrayBuffer(const std::shared_ptr<margelo::nitro::ArrayBuffer>& buffer) {
6
+ inline std::shared_ptr<margelo::nitro::NativeArrayBuffer> ToNativeArrayBuffer(const std::shared_ptr<margelo::nitro::ArrayBuffer>& buffer) {
8
7
  size_t bufferSize = buffer.get()->size();
9
8
  uint8_t* data = new uint8_t[bufferSize];
10
9
  memcpy(data, buffer.get()->data(), bufferSize);
@@ -0,0 +1,157 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.cipherExports = void 0;
7
+ exports.createCipheriv = createCipheriv;
8
+ exports.createDecipheriv = createDecipheriv;
9
+ exports.getCiphers = getCiphers;
10
+ var _reactNativeNitroModules = require("react-native-nitro-modules");
11
+ var _readableStream = _interopRequireDefault(require("readable-stream"));
12
+ var _reactNativeBuffer = require("@craftzdog/react-native-buffer");
13
+ var _utils = require("./utils");
14
+ var _cipher = require("./utils/cipher");
15
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
16
+ // @types/node
17
+
18
+ class CipherUtils {
19
+ static native = _reactNativeNitroModules.NitroModules.createHybridObject('Cipher');
20
+ static getSupportedCiphers() {
21
+ return this.native.getSupportedCiphers();
22
+ }
23
+ }
24
+ function getCiphers() {
25
+ return CipherUtils.getSupportedCiphers();
26
+ }
27
+ class CipherCommon extends _readableStream.default.Transform {
28
+ constructor({
29
+ isCipher,
30
+ cipherType,
31
+ cipherKey,
32
+ iv,
33
+ options
34
+ }) {
35
+ // Explicitly create TransformOptions for super()
36
+ const streamOptions = {};
37
+ if (options) {
38
+ // List known TransformOptions keys (adjust if needed)
39
+ const transformKeys = ['readableHighWaterMark', 'writableHighWaterMark', 'decodeStrings', 'defaultEncoding', 'objectMode', 'destroy', 'read', 'write', 'writev', 'final', 'transform', 'flush'
40
+ // Add any other relevant keys from readable-stream's TransformOptions
41
+ ];
42
+ for (const key of transformKeys) {
43
+ if (key in options) {
44
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
45
+ streamOptions[key] = options[key];
46
+ }
47
+ }
48
+ }
49
+ super(streamOptions); // Pass filtered options
50
+
51
+ const authTagLen = (0, _cipher.getUIntOption)(options ?? {}, 'authTagLength') !== -1 ? (0, _cipher.getUIntOption)(options ?? {}, 'authTagLength') : 16; // defaults to 16 bytes
52
+
53
+ const factory = _reactNativeNitroModules.NitroModules.createHybridObject('CipherFactory');
54
+ this.native = factory.createCipher({
55
+ isCipher,
56
+ cipherType,
57
+ cipherKey: (0, _utils.binaryLikeToArrayBuffer)(cipherKey),
58
+ iv: (0, _utils.binaryLikeToArrayBuffer)(iv),
59
+ authTagLen
60
+ });
61
+ }
62
+ update(data, inputEncoding, outputEncoding) {
63
+ const defaultEncoding = (0, _cipher.getDefaultEncoding)();
64
+ inputEncoding = inputEncoding ?? defaultEncoding;
65
+ outputEncoding = outputEncoding ?? defaultEncoding;
66
+ if (typeof data === 'string') {
67
+ (0, _cipher.validateEncoding)(data, inputEncoding);
68
+ } else if (!ArrayBuffer.isView(data)) {
69
+ throw new Error('Invalid data argument');
70
+ }
71
+ const ret = this.native.update((0, _utils.binaryLikeToArrayBuffer)(data, inputEncoding));
72
+ if (outputEncoding && outputEncoding !== 'buffer') {
73
+ return (0, _utils.ab2str)(ret, outputEncoding);
74
+ }
75
+ return _reactNativeBuffer.Buffer.from(ret);
76
+ }
77
+ final(outputEncoding) {
78
+ const ret = this.native.final();
79
+ if (outputEncoding && outputEncoding !== 'buffer') {
80
+ return (0, _utils.ab2str)(ret, outputEncoding);
81
+ }
82
+ return _reactNativeBuffer.Buffer.from(ret);
83
+ }
84
+ _transform(chunk, encoding, callback) {
85
+ this.push(this.update(chunk, (0, _cipher.normalizeEncoding)(encoding)));
86
+ callback();
87
+ }
88
+ _flush(callback) {
89
+ this.push(this.final());
90
+ callback();
91
+ }
92
+ setAutoPadding(autoPadding) {
93
+ const res = this.native.setAutoPadding(!!autoPadding);
94
+ if (!res) {
95
+ throw new Error('setAutoPadding failed');
96
+ }
97
+ return this;
98
+ }
99
+ setAAD(buffer, options) {
100
+ // Check if native parts are initialized
101
+ if (!this.native || typeof this.native.setAAD !== 'function') {
102
+ throw new Error('Cipher native object or setAAD method not initialized.');
103
+ }
104
+ const res = this.native.setAAD(buffer.buffer, options?.plaintextLength);
105
+ if (!res) {
106
+ throw new Error('setAAD failed (native call returned false)');
107
+ }
108
+ return this;
109
+ }
110
+ getAuthTag() {
111
+ return _reactNativeBuffer.Buffer.from(this.native.getAuthTag());
112
+ }
113
+ setAuthTag(tag) {
114
+ const res = this.native.setAuthTag((0, _utils.binaryLikeToArrayBuffer)(tag));
115
+ if (!res) {
116
+ throw new Error('setAuthTag failed');
117
+ }
118
+ return this;
119
+ }
120
+ getSupportedCiphers() {
121
+ return this.native.getSupportedCiphers();
122
+ }
123
+ }
124
+ class Cipheriv extends CipherCommon {
125
+ constructor(cipherType, cipherKey, iv, options) {
126
+ super({
127
+ isCipher: true,
128
+ cipherType,
129
+ cipherKey: (0, _utils.binaryLikeToArrayBuffer)(cipherKey),
130
+ iv: (0, _utils.binaryLikeToArrayBuffer)(iv),
131
+ options
132
+ });
133
+ }
134
+ }
135
+ class Decipheriv extends CipherCommon {
136
+ constructor(cipherType, cipherKey, iv, options) {
137
+ super({
138
+ isCipher: false,
139
+ cipherType,
140
+ cipherKey: (0, _utils.binaryLikeToArrayBuffer)(cipherKey),
141
+ iv: (0, _utils.binaryLikeToArrayBuffer)(iv),
142
+ options
143
+ });
144
+ }
145
+ }
146
+ function createDecipheriv(algorithm, key, iv, options) {
147
+ return new Decipheriv(algorithm, key, iv, options);
148
+ }
149
+ function createCipheriv(algorithm, key, iv, options) {
150
+ return new Cipheriv(algorithm, key, iv, options);
151
+ }
152
+ const cipherExports = exports.cipherExports = {
153
+ createCipheriv,
154
+ createDecipheriv,
155
+ getCiphers
156
+ };
157
+ //# sourceMappingURL=cipher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_reactNativeNitroModules","require","_readableStream","_interopRequireDefault","_reactNativeBuffer","_utils","_cipher","e","__esModule","default","CipherUtils","native","NitroModules","createHybridObject","getSupportedCiphers","getCiphers","CipherCommon","Stream","Transform","constructor","isCipher","cipherType","cipherKey","iv","options","streamOptions","transformKeys","key","authTagLen","getUIntOption","factory","createCipher","binaryLikeToArrayBuffer","update","data","inputEncoding","outputEncoding","defaultEncoding","getDefaultEncoding","validateEncoding","ArrayBuffer","isView","Error","ret","ab2str","Buffer","from","final","_transform","chunk","encoding","callback","push","normalizeEncoding","_flush","setAutoPadding","autoPadding","res","setAAD","buffer","plaintextLength","getAuthTag","setAuthTag","tag","Cipheriv","Decipheriv","createDecipheriv","algorithm","createCipheriv","cipherExports","exports"],"sourceRoot":"../../src","sources":["cipher.ts"],"mappings":"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","ignoreList":[]}
@@ -19,23 +19,26 @@ function getHashes() {
19
19
  return HashUtils.getSupportedHashAlgorithms();
20
20
  }
21
21
  class Hash extends _readableStream.Stream.Transform {
22
+ validate(args) {
23
+ if (typeof args.algorithm !== 'string' || args.algorithm.length === 0) throw new Error('Algorithm must be a non-empty string');
24
+ if (args.options?.outputLength !== undefined && args.options.outputLength < 0) throw new Error('Output length must be a non-negative number');
25
+ if (args.options?.outputLength !== undefined && typeof args.options.outputLength !== 'number') throw new Error('Output length must be a number');
26
+ }
27
+
22
28
  /**
23
29
  * @internal use `createHash()` instead
24
30
  */
25
- constructor({
26
- algorithm,
27
- options,
28
- native
29
- }) {
30
- super(options);
31
- this.algorithm = algorithm;
32
- this.options = options ?? {};
33
- if (native) {
34
- this.native = native;
35
- } else {
36
- this.native = _reactNativeNitroModules.NitroModules.createHybridObject('Hash');
37
- this.native.createHash(algorithm, this.options.outputLength);
31
+ constructor(args) {
32
+ super(args.options);
33
+ this.validate(args);
34
+ this.algorithm = args.algorithm;
35
+ this.options = args.options ?? {};
36
+ if (args.native) {
37
+ this.native = args.native;
38
+ return;
38
39
  }
40
+ this.native = _reactNativeNitroModules.NitroModules.createHybridObject('Hash');
41
+ this.native.createHash(this.algorithm, this.options.outputLength);
39
42
  }
40
43
 
41
44
  /**
@@ -53,10 +56,7 @@ class Hash extends _readableStream.Stream.Transform {
53
56
  const defaultEncoding = 'utf8';
54
57
  inputEncoding = inputEncoding ?? defaultEncoding;
55
58
  this.native.update((0, _utils.binaryLikeToArrayBuffer)(data, inputEncoding));
56
- if (typeof data === 'string' && inputEncoding !== 'buffer') {
57
- return this; // to support chaining syntax createHash().update().digest()
58
- }
59
- return Buffer.from([]); // returning empty buffer as _flush calls digest
59
+ return this; // to support chaining syntax createHash().update().digest()
60
60
  }
61
61
 
62
62
  /**
@@ -123,7 +123,7 @@ class Hash extends _readableStream.Stream.Transform {
123
123
 
124
124
  // stream interface
125
125
  _transform(chunk, encoding, callback) {
126
- this.push(this.update(chunk, encoding));
126
+ this.update(chunk, encoding);
127
127
  callback();
128
128
  }
129
129
  _flush(callback) {
@@ -131,6 +131,29 @@ class Hash extends _readableStream.Stream.Transform {
131
131
  callback();
132
132
  }
133
133
  }
134
+
135
+ /**
136
+ * Creates and returns a `Hash` object that can be used to generate hash digests
137
+ * using the given `algorithm`. Optional `options` argument controls stream
138
+ * behavior. For XOF hash functions such as `'shake256'`, the `outputLength` option
139
+ * can be used to specify the desired output length in bytes.
140
+ *
141
+ * The `algorithm` is dependent on the available algorithms supported by the
142
+ * version of OpenSSL on the platform. Examples are `'sha256'`, `'sha512'`, etc.
143
+ * On recent releases of OpenSSL, `openssl list -digest-algorithms` will
144
+ * display the available digest algorithms.
145
+ *
146
+ * Example: generating the sha256 sum of a file
147
+ *
148
+ * ```js
149
+ * import crypto from 'react-native-quick-crypto';
150
+ *
151
+ * const hash = crypto.createHash('sha256').update('Test123').digest('hex');
152
+ * console.log('SHA-256 of "Test123":', hash);
153
+ * ```
154
+ * @since v1.0.0
155
+ * @param options `stream.transform` options
156
+ */
134
157
  function createHash(algorithm, options) {
135
158
  // @ts-expect-error private constructor
136
159
  return new Hash({