expo-crypto 15.0.9-canary-20260105-6b962e6 → 15.1.0-canary-20260113-0ce2b9c

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 (98) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/android/build.gradle +2 -2
  3. package/android/src/main/java/expo/modules/crypto/aes/AesConfig.kt +9 -0
  4. package/android/src/main/java/expo/modules/crypto/aes/AesCryptoModule.kt +169 -0
  5. package/android/src/main/java/expo/modules/crypto/aes/AesExceptions.kt +18 -0
  6. package/android/src/main/java/expo/modules/crypto/aes/enums/DataFormat.kt +8 -0
  7. package/android/src/main/java/expo/modules/crypto/aes/enums/KeyEncoding.kt +8 -0
  8. package/android/src/main/java/expo/modules/crypto/aes/enums/KeySize.kt +19 -0
  9. package/android/src/main/java/expo/modules/crypto/aes/extensions/ByteArrayExtensions.kt +31 -0
  10. package/android/src/main/java/expo/modules/crypto/aes/extensions/CipherExtensions.kt +24 -0
  11. package/android/src/main/java/expo/modules/crypto/aes/objects/EncryptionKey.kt +32 -0
  12. package/android/src/main/java/expo/modules/crypto/aes/objects/SealedData.kt +79 -0
  13. package/android/src/main/java/expo/modules/crypto/aes/records/CiphertextOptions.kt +10 -0
  14. package/android/src/main/java/expo/modules/crypto/aes/records/DecryptOptions.kt +16 -0
  15. package/android/src/main/java/expo/modules/crypto/aes/records/EncryptOptions.kt +44 -0
  16. package/android/src/main/java/expo/modules/crypto/aes/records/SealedDataConfig.kt +11 -0
  17. package/build/Crypto.d.ts +1 -0
  18. package/build/Crypto.d.ts.map +1 -1
  19. package/build/Crypto.js +1 -0
  20. package/build/Crypto.js.map +1 -1
  21. package/build/aes/ExpoCryptoAES.d.ts +123 -0
  22. package/build/aes/ExpoCryptoAES.d.ts.map +1 -0
  23. package/build/aes/ExpoCryptoAES.js +4 -0
  24. package/build/aes/ExpoCryptoAES.js.map +1 -0
  25. package/build/aes/ExpoCryptoAES.web.d.ts +41 -0
  26. package/build/aes/ExpoCryptoAES.web.d.ts.map +1 -0
  27. package/build/aes/ExpoCryptoAES.web.js +166 -0
  28. package/build/aes/ExpoCryptoAES.web.js.map +1 -0
  29. package/build/aes/aes.types.d.ts +115 -0
  30. package/build/aes/aes.types.d.ts.map +1 -0
  31. package/build/aes/aes.types.js +16 -0
  32. package/build/aes/aes.types.js.map +1 -0
  33. package/build/aes/index.d.ts +59 -0
  34. package/build/aes/index.d.ts.map +1 -0
  35. package/build/aes/index.js +73 -0
  36. package/build/aes/index.js.map +1 -0
  37. package/build/aes/web-utils.d.ts +7 -0
  38. package/build/aes/web-utils.d.ts.map +1 -0
  39. package/build/aes/web-utils.js +49 -0
  40. package/build/aes/web-utils.js.map +1 -0
  41. package/expo-module.config.json +3 -3
  42. package/ios/AES/AesCryptoModule.swift +212 -0
  43. package/ios/AES/EncryptionKey.swift +76 -0
  44. package/ios/AES/Exceptions.swift +32 -0
  45. package/ios/AES/SealedData.swift +80 -0
  46. package/ios/AES/Utilities.swift +52 -0
  47. package/local-maven-repo/host/exp/exponent/expo.modules.crypto/15.1.0-canary-20260113-0ce2b9c/expo.modules.crypto-15.1.0-canary-20260113-0ce2b9c-sources.jar +0 -0
  48. package/local-maven-repo/host/exp/exponent/expo.modules.crypto/15.1.0-canary-20260113-0ce2b9c/expo.modules.crypto-15.1.0-canary-20260113-0ce2b9c-sources.jar.md5 +1 -0
  49. package/local-maven-repo/host/exp/exponent/expo.modules.crypto/15.1.0-canary-20260113-0ce2b9c/expo.modules.crypto-15.1.0-canary-20260113-0ce2b9c-sources.jar.sha1 +1 -0
  50. package/local-maven-repo/host/exp/exponent/expo.modules.crypto/15.1.0-canary-20260113-0ce2b9c/expo.modules.crypto-15.1.0-canary-20260113-0ce2b9c-sources.jar.sha256 +1 -0
  51. package/local-maven-repo/host/exp/exponent/expo.modules.crypto/15.1.0-canary-20260113-0ce2b9c/expo.modules.crypto-15.1.0-canary-20260113-0ce2b9c-sources.jar.sha512 +1 -0
  52. package/local-maven-repo/host/exp/exponent/expo.modules.crypto/15.1.0-canary-20260113-0ce2b9c/expo.modules.crypto-15.1.0-canary-20260113-0ce2b9c.aar +0 -0
  53. package/local-maven-repo/host/exp/exponent/expo.modules.crypto/15.1.0-canary-20260113-0ce2b9c/expo.modules.crypto-15.1.0-canary-20260113-0ce2b9c.aar.md5 +1 -0
  54. package/local-maven-repo/host/exp/exponent/expo.modules.crypto/15.1.0-canary-20260113-0ce2b9c/expo.modules.crypto-15.1.0-canary-20260113-0ce2b9c.aar.sha1 +1 -0
  55. package/local-maven-repo/host/exp/exponent/expo.modules.crypto/15.1.0-canary-20260113-0ce2b9c/expo.modules.crypto-15.1.0-canary-20260113-0ce2b9c.aar.sha256 +1 -0
  56. package/local-maven-repo/host/exp/exponent/expo.modules.crypto/15.1.0-canary-20260113-0ce2b9c/expo.modules.crypto-15.1.0-canary-20260113-0ce2b9c.aar.sha512 +1 -0
  57. package/local-maven-repo/host/exp/exponent/expo.modules.crypto/15.1.0-canary-20260113-0ce2b9c/expo.modules.crypto-15.1.0-canary-20260113-0ce2b9c.module +87 -0
  58. package/local-maven-repo/host/exp/exponent/expo.modules.crypto/15.1.0-canary-20260113-0ce2b9c/expo.modules.crypto-15.1.0-canary-20260113-0ce2b9c.module.md5 +1 -0
  59. package/local-maven-repo/host/exp/exponent/expo.modules.crypto/15.1.0-canary-20260113-0ce2b9c/expo.modules.crypto-15.1.0-canary-20260113-0ce2b9c.module.sha1 +1 -0
  60. package/local-maven-repo/host/exp/exponent/expo.modules.crypto/15.1.0-canary-20260113-0ce2b9c/expo.modules.crypto-15.1.0-canary-20260113-0ce2b9c.module.sha256 +1 -0
  61. package/local-maven-repo/host/exp/exponent/expo.modules.crypto/15.1.0-canary-20260113-0ce2b9c/expo.modules.crypto-15.1.0-canary-20260113-0ce2b9c.module.sha512 +1 -0
  62. package/local-maven-repo/host/exp/exponent/expo.modules.crypto/{15.0.9-canary-20260105-6b962e6/expo.modules.crypto-15.0.9-canary-20260105-6b962e6.pom → 15.1.0-canary-20260113-0ce2b9c/expo.modules.crypto-15.1.0-canary-20260113-0ce2b9c.pom} +1 -1
  63. package/local-maven-repo/host/exp/exponent/expo.modules.crypto/15.1.0-canary-20260113-0ce2b9c/expo.modules.crypto-15.1.0-canary-20260113-0ce2b9c.pom.md5 +1 -0
  64. package/local-maven-repo/host/exp/exponent/expo.modules.crypto/15.1.0-canary-20260113-0ce2b9c/expo.modules.crypto-15.1.0-canary-20260113-0ce2b9c.pom.sha1 +1 -0
  65. package/local-maven-repo/host/exp/exponent/expo.modules.crypto/15.1.0-canary-20260113-0ce2b9c/expo.modules.crypto-15.1.0-canary-20260113-0ce2b9c.pom.sha256 +1 -0
  66. package/local-maven-repo/host/exp/exponent/expo.modules.crypto/15.1.0-canary-20260113-0ce2b9c/expo.modules.crypto-15.1.0-canary-20260113-0ce2b9c.pom.sha512 +1 -0
  67. package/local-maven-repo/host/exp/exponent/expo.modules.crypto/maven-metadata.xml +4 -4
  68. package/local-maven-repo/host/exp/exponent/expo.modules.crypto/maven-metadata.xml.md5 +1 -1
  69. package/local-maven-repo/host/exp/exponent/expo.modules.crypto/maven-metadata.xml.sha1 +1 -1
  70. package/local-maven-repo/host/exp/exponent/expo.modules.crypto/maven-metadata.xml.sha256 +1 -1
  71. package/local-maven-repo/host/exp/exponent/expo.modules.crypto/maven-metadata.xml.sha512 +1 -1
  72. package/mocks/ExpoCryptoAES.ts +34 -0
  73. package/package.json +3 -3
  74. package/src/Crypto.ts +1 -0
  75. package/src/aes/ExpoCryptoAES.ts +147 -0
  76. package/src/aes/ExpoCryptoAES.web.ts +249 -0
  77. package/src/aes/aes.types.ts +126 -0
  78. package/src/aes/index.ts +150 -0
  79. package/src/aes/web-utils.ts +58 -0
  80. package/local-maven-repo/host/exp/exponent/expo.modules.crypto/15.0.9-canary-20260105-6b962e6/expo.modules.crypto-15.0.9-canary-20260105-6b962e6-sources.jar +0 -0
  81. package/local-maven-repo/host/exp/exponent/expo.modules.crypto/15.0.9-canary-20260105-6b962e6/expo.modules.crypto-15.0.9-canary-20260105-6b962e6-sources.jar.md5 +0 -1
  82. package/local-maven-repo/host/exp/exponent/expo.modules.crypto/15.0.9-canary-20260105-6b962e6/expo.modules.crypto-15.0.9-canary-20260105-6b962e6-sources.jar.sha1 +0 -1
  83. package/local-maven-repo/host/exp/exponent/expo.modules.crypto/15.0.9-canary-20260105-6b962e6/expo.modules.crypto-15.0.9-canary-20260105-6b962e6-sources.jar.sha256 +0 -1
  84. package/local-maven-repo/host/exp/exponent/expo.modules.crypto/15.0.9-canary-20260105-6b962e6/expo.modules.crypto-15.0.9-canary-20260105-6b962e6-sources.jar.sha512 +0 -1
  85. package/local-maven-repo/host/exp/exponent/expo.modules.crypto/15.0.9-canary-20260105-6b962e6/expo.modules.crypto-15.0.9-canary-20260105-6b962e6.aar +0 -0
  86. package/local-maven-repo/host/exp/exponent/expo.modules.crypto/15.0.9-canary-20260105-6b962e6/expo.modules.crypto-15.0.9-canary-20260105-6b962e6.aar.md5 +0 -1
  87. package/local-maven-repo/host/exp/exponent/expo.modules.crypto/15.0.9-canary-20260105-6b962e6/expo.modules.crypto-15.0.9-canary-20260105-6b962e6.aar.sha1 +0 -1
  88. package/local-maven-repo/host/exp/exponent/expo.modules.crypto/15.0.9-canary-20260105-6b962e6/expo.modules.crypto-15.0.9-canary-20260105-6b962e6.aar.sha256 +0 -1
  89. package/local-maven-repo/host/exp/exponent/expo.modules.crypto/15.0.9-canary-20260105-6b962e6/expo.modules.crypto-15.0.9-canary-20260105-6b962e6.aar.sha512 +0 -1
  90. package/local-maven-repo/host/exp/exponent/expo.modules.crypto/15.0.9-canary-20260105-6b962e6/expo.modules.crypto-15.0.9-canary-20260105-6b962e6.module +0 -87
  91. package/local-maven-repo/host/exp/exponent/expo.modules.crypto/15.0.9-canary-20260105-6b962e6/expo.modules.crypto-15.0.9-canary-20260105-6b962e6.module.md5 +0 -1
  92. package/local-maven-repo/host/exp/exponent/expo.modules.crypto/15.0.9-canary-20260105-6b962e6/expo.modules.crypto-15.0.9-canary-20260105-6b962e6.module.sha1 +0 -1
  93. package/local-maven-repo/host/exp/exponent/expo.modules.crypto/15.0.9-canary-20260105-6b962e6/expo.modules.crypto-15.0.9-canary-20260105-6b962e6.module.sha256 +0 -1
  94. package/local-maven-repo/host/exp/exponent/expo.modules.crypto/15.0.9-canary-20260105-6b962e6/expo.modules.crypto-15.0.9-canary-20260105-6b962e6.module.sha512 +0 -1
  95. package/local-maven-repo/host/exp/exponent/expo.modules.crypto/15.0.9-canary-20260105-6b962e6/expo.modules.crypto-15.0.9-canary-20260105-6b962e6.pom.md5 +0 -1
  96. package/local-maven-repo/host/exp/exponent/expo.modules.crypto/15.0.9-canary-20260105-6b962e6/expo.modules.crypto-15.0.9-canary-20260105-6b962e6.pom.sha1 +0 -1
  97. package/local-maven-repo/host/exp/exponent/expo.modules.crypto/15.0.9-canary-20260105-6b962e6/expo.modules.crypto-15.0.9-canary-20260105-6b962e6.pom.sha256 +0 -1
  98. package/local-maven-repo/host/exp/exponent/expo.modules.crypto/15.0.9-canary-20260105-6b962e6/expo.modules.crypto-15.0.9-canary-20260105-6b962e6.pom.sha512 +0 -1
package/CHANGELOG.md CHANGED
@@ -6,6 +6,8 @@
6
6
 
7
7
  ### 🎉 New features
8
8
 
9
+ - Added support for AES-GCM encryption. ([#41249](https://github.com/expo/expo/pull/41249) by [@barthap](https://github.com/barthap))
10
+
9
11
  ### 🐛 Bug fixes
10
12
 
11
13
  ### 💡 Others
@@ -4,13 +4,13 @@ plugins {
4
4
  }
5
5
 
6
6
  group = 'host.exp.exponent'
7
- version = '15.0.9-canary-20260105-6b962e6'
7
+ version = '15.1.0-canary-20260113-0ce2b9c'
8
8
 
9
9
  android {
10
10
  namespace "expo.modules.crypto"
11
11
  defaultConfig {
12
12
  versionCode 25
13
- versionName "15.0.9-canary-20260105-6b962e6"
13
+ versionName "15.1.0-canary-20260113-0ce2b9c"
14
14
  }
15
15
  }
16
16
 
@@ -0,0 +1,9 @@
1
+ package expo.modules.crypto.aes
2
+
3
+ object AesConfig {
4
+ const val DEFAULT_IV_SIZE: Int = 12
5
+ const val DEFAULT_TAG_SIZE: Int = 16
6
+
7
+ const val CRYPTO_KEY_ALGORITHM = "AES"
8
+ const val CIPHER_TRANSFORMATION_NAME = "AES/GCM/NoPadding"
9
+ }
@@ -0,0 +1,169 @@
1
+ package expo.modules.crypto.aes
2
+
3
+ import android.util.Base64
4
+ import expo.modules.crypto.aes.AesConfig.CIPHER_TRANSFORMATION_NAME
5
+ import expo.modules.crypto.aes.AesConfig.DEFAULT_TAG_SIZE
6
+ import expo.modules.crypto.aes.enums.DataFormat
7
+ import expo.modules.crypto.aes.enums.KeyEncoding
8
+ import expo.modules.crypto.aes.enums.KeySize
9
+ import expo.modules.crypto.aes.extensions.decrypt
10
+ import expo.modules.crypto.aes.extensions.encoded
11
+ import expo.modules.crypto.aes.extensions.encrypt
12
+ import expo.modules.crypto.aes.extensions.formatted
13
+ import expo.modules.crypto.aes.objects.EncryptionKey
14
+ import expo.modules.crypto.aes.objects.SealedData
15
+ import expo.modules.crypto.aes.records.CiphertextOptions
16
+ import expo.modules.crypto.aes.records.DecryptOptions
17
+ import expo.modules.crypto.aes.records.EncryptOptions
18
+ import expo.modules.crypto.aes.records.SealedDataConfig
19
+ import expo.modules.kotlin.apifeatures.EitherType
20
+ import expo.modules.kotlin.exception.Exceptions
21
+ import expo.modules.kotlin.modules.Module
22
+ import expo.modules.kotlin.modules.ModuleDefinition
23
+ import expo.modules.kotlin.types.Either
24
+ import java.nio.ByteBuffer
25
+ import java.security.SecureRandom
26
+ import javax.crypto.Cipher
27
+ import javax.crypto.spec.GCMParameterSpec
28
+
29
+ @OptIn(EitherType::class)
30
+ typealias BinaryInput = Either<ByteArray, String>
31
+
32
+ @OptIn(EitherType::class, ExperimentalStdlibApi::class)
33
+ class AesCryptoModule : Module() {
34
+ private val rng: SecureRandom by lazy { SecureRandom() }
35
+
36
+ override fun definition() = ModuleDefinition {
37
+ Name("ExpoCryptoAES")
38
+
39
+ AsyncFunction("encryptAsync", this@AesCryptoModule::encrypt)
40
+ AsyncFunction("decryptAsync", this@AesCryptoModule::decrypt)
41
+
42
+ Class("EncryptionKey", EncryptionKey::class) {
43
+ Constructor {
44
+ throw Exceptions.IllegalArgument("EncryptionKey constructor cannot be used directly")
45
+ }
46
+
47
+ StaticAsyncFunction("generate") { size: KeySize? ->
48
+ EncryptionKey(size ?: KeySize.AES256)
49
+ }
50
+ StaticAsyncFunction("import") { input: Either<ByteArray, String>, encoding: KeyEncoding? ->
51
+ val bytes = if (input.`is`(ByteArray::class)) {
52
+ input.get(ByteArray::class)
53
+ } else {
54
+ val encodedString = input.get(String::class)
55
+ when (encoding) {
56
+ null -> throw MissingStringEncodingException()
57
+ KeyEncoding.BASE64 -> Base64.decode(encodedString, Base64.NO_WRAP)
58
+ KeyEncoding.HEX ->
59
+ encodedString
60
+ .lowercase()
61
+ .substringAfter("0x")
62
+ .hexToByteArray(HexFormat.Default)
63
+ }
64
+ }
65
+ EncryptionKey(bytes)
66
+ }
67
+
68
+ AsyncFunction("bytes") { key: EncryptionKey -> key.bytes }
69
+ AsyncFunction("encoded") { key: EncryptionKey, encoding: KeyEncoding ->
70
+ key.bytes.encoded(encoding)
71
+ }
72
+
73
+ Property("size") { key: EncryptionKey -> key.keySize }
74
+ }
75
+
76
+ Class("SealedData", SealedData::class) {
77
+ Constructor {
78
+ throw Exceptions.IllegalArgument("SealedData constructor cannot be used directly")
79
+ }
80
+
81
+ StaticFunction("fromParts", this@AesCryptoModule::sealedDataFromParts)
82
+ StaticFunction("fromCombined") { combined: ByteArray, config: SealedDataConfig? ->
83
+ val config = config ?: SealedDataConfig()
84
+ SealedData(config, content = combined)
85
+ }
86
+
87
+ AsyncFunction("iv") { sealedData: SealedData, format: DataFormat? ->
88
+ sealedData.ivBytes.formatted(format)
89
+ }
90
+ AsyncFunction("tag") { sealedData: SealedData, format: DataFormat? ->
91
+ sealedData.tagBytes.formatted(format)
92
+ }
93
+ AsyncFunction("combined") { sealedData: SealedData, format: DataFormat? ->
94
+ sealedData.combinedArray.formatted(format)
95
+ }
96
+ AsyncFunction("ciphertext") { sealedData: SealedData, options: CiphertextOptions? ->
97
+ val (includeTag, outputFormat) = options ?: CiphertextOptions()
98
+ sealedData.ciphertextBytes(withTag = includeTag).formatted(outputFormat)
99
+ }
100
+
101
+ Property("combinedSize") { sealedData -> sealedData.combinedSize }
102
+ Property("ivSize") { sealedData -> sealedData.ivSize }
103
+ Property("tagSize") { sealedData -> sealedData.tagSize }
104
+ }
105
+ }
106
+
107
+ private fun encrypt(
108
+ plaintext: BinaryInput,
109
+ key: EncryptionKey,
110
+ options: EncryptOptions?
111
+ ): SealedData {
112
+ val key = key.cryptoKey
113
+ val plaintextBuffer = ByteBuffer.wrap(plaintext.toBytes())
114
+
115
+ try {
116
+ val cipher = Cipher.getInstance(CIPHER_TRANSFORMATION_NAME).apply {
117
+ val params = options?.gcmParameterSpec(rng)
118
+ init(Cipher.ENCRYPT_MODE, key, params)
119
+ options?.additionalData?.let { updateAAD(it.toBytes()) }
120
+ }
121
+ return cipher.encrypt(plaintextBuffer)
122
+ } catch (err: Throwable) {
123
+ throw EncryptionFailed(err)
124
+ }
125
+ }
126
+
127
+ private fun decrypt(
128
+ sealedData: SealedData,
129
+ key: EncryptionKey,
130
+ options: DecryptOptions?
131
+ ): Any {
132
+ val key = key.cryptoKey
133
+
134
+ try {
135
+ val cipher = Cipher.getInstance(CIPHER_TRANSFORMATION_NAME).apply {
136
+ val spec = GCMParameterSpec(sealedData.tagSize * 8, sealedData.ivBytes)
137
+ init(Cipher.DECRYPT_MODE, key, spec)
138
+ }
139
+ options?.additionalData?.let { cipher.updateAAD(it.toBytes()) }
140
+
141
+ val plaintext = cipher.decrypt(sealedData)
142
+ return plaintext.array().formatted(options?.output)
143
+ } catch (err: Throwable) {
144
+ throw DecryptionFailed(err)
145
+ }
146
+ }
147
+
148
+ private fun sealedDataFromParts(iv: BinaryInput, ciphertext: BinaryInput, tag: Either<ByteArray, Int>?): SealedData {
149
+ val iv = iv.toBytes()
150
+ val ciphertext = ciphertext.toBytes()
151
+ return if (tag?.`is`(Int::class) == true) {
152
+ val tagLength = tag.get(Int::class)
153
+ SealedData(iv, ciphertext, tagLength)
154
+ } else if (tag?.`is`(ByteArray::class) == true) {
155
+ val tag = tag.get(ByteArray::class)
156
+ SealedData(iv, ciphertext + tag, tag.size)
157
+ } else {
158
+ SealedData(iv, ciphertext, DEFAULT_TAG_SIZE)
159
+ }
160
+ }
161
+
162
+ private fun BinaryInput.toBytes(): ByteArray {
163
+ if (this.`is`(ByteArray::class)) {
164
+ return this.get(ByteArray::class)
165
+ }
166
+
167
+ return Base64.decode(this.get(String::class), Base64.NO_WRAP)
168
+ }
169
+ }
@@ -0,0 +1,18 @@
1
+ package expo.modules.crypto.aes
2
+
3
+ import expo.modules.core.errors.CodedException
4
+
5
+ class MissingStringEncodingException :
6
+ CodedException("'encoding' argument must be provided for string input")
7
+
8
+ class InvalidKeyLengthException(byteLength: Int) :
9
+ CodedException("EncryptionKey cannot be created from bytes of length '$byteLength'")
10
+
11
+ class InvalidSealedDataConfigException :
12
+ CodedException("Invalid SealedData config")
13
+
14
+ class EncryptionFailed(cause: Throwable) :
15
+ CodedException("AES encryption failed: ${cause.message}", cause)
16
+
17
+ class DecryptionFailed(cause: Throwable) :
18
+ CodedException("AES decryption failed: ${cause.message}", cause)
@@ -0,0 +1,8 @@
1
+ package expo.modules.crypto.aes.enums
2
+
3
+ import expo.modules.kotlin.types.Enumerable
4
+
5
+ enum class DataFormat(val value: String) : Enumerable {
6
+ BYTES("bytes"),
7
+ BASE64("base64")
8
+ }
@@ -0,0 +1,8 @@
1
+ package expo.modules.crypto.aes.enums
2
+
3
+ import expo.modules.kotlin.types.Enumerable
4
+
5
+ enum class KeyEncoding(val value: String) : Enumerable {
6
+ BASE64("base64"),
7
+ HEX("hex")
8
+ }
@@ -0,0 +1,19 @@
1
+ package expo.modules.crypto.aes.enums
2
+
3
+ import expo.modules.crypto.aes.InvalidKeyLengthException
4
+ import expo.modules.kotlin.types.Enumerable
5
+
6
+ enum class KeySize(val bitSize: Int) : Enumerable {
7
+ AES128(128),
8
+ AES192(192),
9
+ AES256(256);
10
+
11
+ val byteSize: Int
12
+ get() = bitSize / 8
13
+
14
+ companion object {
15
+ fun fromByteLength(byteLen: Int): KeySize =
16
+ entries.find { it.byteSize == byteLen }
17
+ ?: throw InvalidKeyLengthException(byteLen)
18
+ }
19
+ }
@@ -0,0 +1,31 @@
1
+ package expo.modules.crypto.aes.extensions
2
+
3
+ import android.util.Base64
4
+ import expo.modules.crypto.aes.enums.DataFormat
5
+ import expo.modules.crypto.aes.enums.KeyEncoding
6
+ import java.nio.ByteBuffer
7
+
8
+ fun ByteBuffer.copiedArray(): ByteArray =
9
+ ByteArray(remaining()).also { get(it) }
10
+
11
+ inline fun ByteArray.init(block: ByteBuffer.() -> Unit): ByteArray = apply {
12
+ ByteBuffer.wrap(this).also { block(it) }
13
+ }
14
+
15
+ fun ByteArray.base64Encoded(): String =
16
+ Base64.encodeToString(this, Base64.NO_WRAP)
17
+
18
+ fun ByteArray.hexEncoded(): String =
19
+ joinToString("") { "%02x".format(it) }
20
+
21
+ fun ByteArray.encoded(encoding: KeyEncoding): String =
22
+ when (encoding) {
23
+ KeyEncoding.HEX -> this.hexEncoded()
24
+ KeyEncoding.BASE64 -> this.base64Encoded()
25
+ }
26
+
27
+ fun ByteArray.formatted(format: DataFormat?): Any =
28
+ when (format) {
29
+ DataFormat.BYTES, null -> this
30
+ DataFormat.BASE64 -> this.base64Encoded()
31
+ }
@@ -0,0 +1,24 @@
1
+ package expo.modules.crypto.aes.extensions
2
+
3
+ import expo.modules.crypto.aes.objects.SealedData
4
+ import java.nio.ByteBuffer
5
+ import javax.crypto.Cipher
6
+
7
+ internal fun Cipher.encrypt(plaintext: ByteBuffer): SealedData {
8
+ val plaintextSize = plaintext.remaining()
9
+ val ciphertextWithTagSize = getOutputSize(plaintextSize)
10
+ val tagSize = ciphertextWithTagSize - plaintextSize
11
+
12
+ return SealedData(iv, plaintextSize, tagSize).also {
13
+ doFinal(plaintext, it.taggedCiphertextBuffer)
14
+ }
15
+ }
16
+
17
+ internal fun Cipher.decrypt(sealedData: SealedData): ByteBuffer {
18
+ val inputBuf = sealedData.taggedCiphertextBuffer
19
+ val plaintextSize = getOutputSize(inputBuf.remaining())
20
+
21
+ return ByteBuffer.allocate(plaintextSize).also { outputBuf ->
22
+ doFinal(inputBuf, outputBuf)
23
+ }
24
+ }
@@ -0,0 +1,32 @@
1
+ package expo.modules.crypto.aes.objects
2
+
3
+ import expo.modules.crypto.aes.AesConfig.CRYPTO_KEY_ALGORITHM
4
+ import expo.modules.crypto.aes.enums.KeySize
5
+ import expo.modules.kotlin.sharedobjects.SharedObject
6
+ import javax.crypto.KeyGenerator
7
+ import javax.crypto.SecretKey
8
+ import javax.crypto.spec.SecretKeySpec
9
+
10
+ class EncryptionKey : SharedObject {
11
+ val keySize: KeySize
12
+ val cryptoKey: SecretKey
13
+
14
+ constructor(size: KeySize) {
15
+ val keygen = KeyGenerator.getInstance(CRYPTO_KEY_ALGORITHM).apply {
16
+ init(size.bitSize)
17
+ }
18
+
19
+ keySize = size
20
+ cryptoKey = keygen.generateKey()
21
+ }
22
+
23
+ constructor(bytes: ByteArray) {
24
+ keySize = KeySize.fromByteLength(bytes.size)
25
+ cryptoKey = SecretKeySpec(bytes, CRYPTO_KEY_ALGORITHM)
26
+ }
27
+
28
+ val bytes: ByteArray
29
+ get() = cryptoKey.encoded
30
+
31
+ override fun getAdditionalMemoryPressure(): Int = keySize.byteSize
32
+ }
@@ -0,0 +1,79 @@
1
+ package expo.modules.crypto.aes.objects
2
+
3
+ import expo.modules.crypto.aes.InvalidSealedDataConfigException
4
+ import expo.modules.crypto.aes.extensions.copiedArray
5
+ import expo.modules.crypto.aes.extensions.init
6
+ import expo.modules.crypto.aes.records.SealedDataConfig
7
+ import expo.modules.kotlin.sharedobjects.SharedObject
8
+ import java.nio.ByteBuffer
9
+
10
+ /**
11
+ * Represents a contiguous memory area containing concatenated IV || ciphertext || tag.
12
+ */
13
+ class SealedData(
14
+ private val config: SealedDataConfig,
15
+ private val content: ByteArray
16
+ ) : SharedObject() {
17
+ init {
18
+ if (content.size < ivSize + tagSize) {
19
+ throw InvalidSealedDataConfigException()
20
+ }
21
+ }
22
+
23
+ /**
24
+ * Initializes sealed data with given IV, and allocates memory for ciphertext and tag.
25
+ */
26
+ constructor(iv: ByteArray, ciphertextLength: Int, tagLength: Int) : this(
27
+ config = SealedDataConfig(ivLength = iv.size, tagLength = tagLength),
28
+ content = ByteArray(iv.size + ciphertextLength + tagLength).init {
29
+ put(iv)
30
+ }
31
+ )
32
+
33
+ /**
34
+ * Constructs sealed data from parts.
35
+ */
36
+ constructor(iv: ByteArray, ciphertextWithTag: ByteArray, tagLength: Int) : this(
37
+ config = SealedDataConfig(ivLength = iv.size, tagLength = tagLength),
38
+ content = iv + ciphertextWithTag
39
+ )
40
+
41
+ // buffers mapping specific memory regions
42
+ private val ivBuffer: ByteBuffer
43
+ get() = ByteBuffer.wrap(content, 0, ivSize)
44
+ private val tagBuffer: ByteBuffer
45
+ get() = ByteBuffer.wrap(content, content.size - tagSize, tagSize)
46
+ private val combinedBuffer: ByteBuffer
47
+ get() = ByteBuffer.wrap(content)
48
+ private val ciphertextBuffer: ByteBuffer
49
+ get() = ByteBuffer.wrap(content, ivSize, ciphertextSize)
50
+
51
+ /** Buffer used by `[javax.crypto.Cipher]` to perform encryption/decryption */
52
+ internal val taggedCiphertextBuffer: ByteBuffer
53
+ get() = ByteBuffer.wrap(content, ivSize, ciphertextSize + tagSize)
54
+
55
+ val combinedSize: Int
56
+ get() = content.size
57
+ val ivSize: Int
58
+ get() = config.ivLength
59
+ val tagSize: Int
60
+ get() = config.tagLength
61
+ val ciphertextSize: Int
62
+ get() = combinedSize - ivSize - tagSize
63
+
64
+ val ivBytes: ByteArray
65
+ get() = ivBuffer.copiedArray()
66
+ val tagBytes: ByteArray
67
+ get() = tagBuffer.copiedArray()
68
+ val combinedArray: ByteArray
69
+ get() = combinedBuffer.array()
70
+
71
+ fun ciphertextBytes(withTag: Boolean): ByteArray =
72
+ if (withTag) {
73
+ taggedCiphertextBuffer
74
+ } else {
75
+ ciphertextBuffer
76
+ }.copiedArray()
77
+
78
+ override fun getAdditionalMemoryPressure(): Int = content.size
79
+ }
@@ -0,0 +1,10 @@
1
+ package expo.modules.crypto.aes.records
2
+
3
+ import expo.modules.crypto.aes.enums.DataFormat
4
+ import expo.modules.kotlin.records.Field
5
+ import expo.modules.kotlin.records.Record
6
+
7
+ data class CiphertextOptions(
8
+ @Field val includeTag: Boolean = false,
9
+ @Field val outputFormat: DataFormat = DataFormat.BYTES
10
+ ) : Record
@@ -0,0 +1,16 @@
1
+ package expo.modules.crypto.aes.records
2
+
3
+ import expo.modules.crypto.aes.BinaryInput
4
+ import expo.modules.crypto.aes.enums.DataFormat
5
+ import expo.modules.kotlin.apifeatures.EitherType
6
+ import expo.modules.kotlin.records.Field
7
+ import expo.modules.kotlin.records.Record
8
+
9
+ @OptIn(EitherType::class)
10
+ class DecryptOptions : Record {
11
+ @Field
12
+ val output: DataFormat = DataFormat.BYTES
13
+
14
+ @Field
15
+ val additionalData: BinaryInput? = null
16
+ }
@@ -0,0 +1,44 @@
1
+ package expo.modules.crypto.aes.records
2
+
3
+ import android.util.Base64
4
+ import expo.modules.crypto.aes.AesConfig.DEFAULT_IV_SIZE
5
+ import expo.modules.crypto.aes.AesConfig.DEFAULT_TAG_SIZE
6
+ import expo.modules.crypto.aes.BinaryInput
7
+ import expo.modules.kotlin.apifeatures.EitherType
8
+ import expo.modules.kotlin.records.Field
9
+ import expo.modules.kotlin.records.Record
10
+ import expo.modules.kotlin.types.EitherOfThree
11
+ import java.security.SecureRandom
12
+ import javax.crypto.spec.GCMParameterSpec
13
+
14
+ @OptIn(EitherType::class)
15
+ class EncryptOptions : Record {
16
+ @Field
17
+ val nonce: EitherOfThree<String, ByteArray, Int>? = null
18
+
19
+ @Field
20
+ val tagLength: Int? = null
21
+
22
+ @Field
23
+ val additionalData: BinaryInput? = null
24
+
25
+ internal fun gcmParameterSpec(random: SecureRandom): GCMParameterSpec? {
26
+ // a default will be generated by Cipher
27
+ if (nonce == null && tagLength == null) {
28
+ return null
29
+ }
30
+
31
+ val iv = if (nonce == null) {
32
+ ByteArray(DEFAULT_IV_SIZE).also { random.nextBytes(it) }
33
+ } else if (nonce.`is`(Int::class)) {
34
+ ByteArray(nonce.get(Int::class)).also { random.nextBytes(it) }
35
+ } else if (nonce.`is`(String::class)) {
36
+ Base64.decode(nonce.get(String::class), Base64.NO_WRAP)
37
+ } else {
38
+ nonce.get(ByteArray::class)
39
+ }
40
+
41
+ val tagByteLength = tagLength ?: DEFAULT_TAG_SIZE
42
+ return GCMParameterSpec(tagByteLength * 8, iv)
43
+ }
44
+ }
@@ -0,0 +1,11 @@
1
+ package expo.modules.crypto.aes.records
2
+
3
+ import expo.modules.crypto.aes.AesConfig.DEFAULT_IV_SIZE
4
+ import expo.modules.crypto.aes.AesConfig.DEFAULT_TAG_SIZE
5
+ import expo.modules.kotlin.records.Field
6
+ import expo.modules.kotlin.records.Record
7
+
8
+ data class SealedDataConfig(
9
+ @Field val ivLength: Int = DEFAULT_IV_SIZE,
10
+ @Field val tagLength: Int = DEFAULT_TAG_SIZE
11
+ ) : Record
package/build/Crypto.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { UintBasedTypedArray, IntBasedTypedArray } from 'expo-modules-core';
2
2
  import { CryptoDigestAlgorithm, CryptoDigestOptions, Digest } from './Crypto.types';
3
3
  export * from './Crypto.types';
4
+ export * from './aes';
4
5
  /**
5
6
  * Generates completely random bytes using native implementations. The `byteCount` property
6
7
  * is a `number` indicating the number of bytes to generate in the form of a `Uint8Array`.
@@ -1 +1 @@
1
- {"version":3,"file":"Crypto.d.ts","sourceRoot":"","sources":["../src/Crypto.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAEjG,OAAO,EAAE,qBAAqB,EAAkB,mBAAmB,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAKpG,cAAc,gBAAgB,CAAC;AAW/B;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,UAAU,CAoB5D;AAGD;;;;;GAKG;AACH,wBAAsB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAUhF;AA0CD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,iBAAiB,CACrC,SAAS,EAAE,qBAAqB,EAChC,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,mBAAsD,GAC9D,OAAO,CAAC,MAAM,CAAC,CAUjB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,eAAe,CAAC,CAAC,SAAS,kBAAkB,GAAG,mBAAmB,EAChF,UAAU,EAAE,CAAC,GACZ,CAAC,CAGH;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAYD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,MAAM,CAAC,SAAS,EAAE,qBAAqB,EAAE,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAcjG"}
1
+ {"version":3,"file":"Crypto.d.ts","sourceRoot":"","sources":["../src/Crypto.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAEjG,OAAO,EAAE,qBAAqB,EAAkB,mBAAmB,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAKpG,cAAc,gBAAgB,CAAC;AAC/B,cAAc,OAAO,CAAC;AAWtB;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,UAAU,CAoB5D;AAGD;;;;;GAKG;AACH,wBAAsB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAUhF;AA0CD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,iBAAiB,CACrC,SAAS,EAAE,qBAAqB,EAChC,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,mBAAsD,GAC9D,OAAO,CAAC,MAAM,CAAC,CAUjB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,eAAe,CAAC,CAAC,SAAS,kBAAkB,GAAG,mBAAmB,EAChF,UAAU,EAAE,CAAC,GACZ,CAAC,CAGH;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAYD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,MAAM,CAAC,SAAS,EAAE,qBAAqB,EAAE,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAcjG"}
package/build/Crypto.js CHANGED
@@ -2,6 +2,7 @@ import { UnavailabilityError } from 'expo-modules-core';
2
2
  import { CryptoDigestAlgorithm, CryptoEncoding } from './Crypto.types';
3
3
  import ExpoCrypto from './ExpoCrypto';
4
4
  export * from './Crypto.types';
5
+ export * from './aes';
5
6
  class CryptoError extends TypeError {
6
7
  code = 'ERR_CRYPTO';
7
8
  constructor(message) {
@@ -1 +1 @@
1
- {"version":3,"file":"Crypto.js","sourceRoot":"","sources":["../src/Crypto.ts"],"names":[],"mappings":"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","sourcesContent":["import { UnavailabilityError, UintBasedTypedArray, IntBasedTypedArray } from 'expo-modules-core';\n\nimport { CryptoDigestAlgorithm, CryptoEncoding, CryptoDigestOptions, Digest } from './Crypto.types';\nimport ExpoCrypto from './ExpoCrypto';\n\ndeclare const global: any;\n\nexport * from './Crypto.types';\n\nclass CryptoError extends TypeError {\n code = 'ERR_CRYPTO';\n\n constructor(message: string) {\n super(`expo-crypto: ${message}`);\n }\n}\n\n// @needsAudit\n/**\n * Generates completely random bytes using native implementations. The `byteCount` property\n * is a `number` indicating the number of bytes to generate in the form of a `Uint8Array`.\n * Falls back to `Math.random` during development to prevent issues with React Native Debugger.\n * @param byteCount - A number within the range from `0` to `1024`. Anything else will throw a `TypeError`.\n * @return An array of random bytes with the same length as the `byteCount`.\n */\nexport function getRandomBytes(byteCount: number): Uint8Array {\n assertByteCount(byteCount, 'getRandomBytes');\n const validByteCount = Math.floor(byteCount);\n if (__DEV__) {\n if (!global.nativeCallSyncHook || global.__REMOTEDEV__) {\n // remote javascript debugging is enabled\n const array = new Uint8Array(validByteCount);\n for (let i = 0; i < validByteCount; i++) {\n array[i] = Math.floor(Math.random() * 256);\n }\n return array;\n }\n }\n if (ExpoCrypto.getRandomValues) {\n const byteArray = new Uint8Array(validByteCount);\n ExpoCrypto.getRandomValues(byteArray);\n return byteArray;\n } else {\n throw new UnavailabilityError('expo-crypto', 'getRandomBytes');\n }\n}\n\n// @needsAudit\n/**\n * Generates completely random bytes using native implementations. The `byteCount` property\n * is a `number` indicating the number of bytes to generate in the form of a `Uint8Array`.\n * @param byteCount - A number within the range from `0` to `1024`. Anything else will throw a `TypeError`.\n * @return A promise that fulfills with an array of random bytes with the same length as the `byteCount`.\n */\nexport async function getRandomBytesAsync(byteCount: number): Promise<Uint8Array> {\n assertByteCount(byteCount, 'getRandomBytesAsync');\n const validByteCount = Math.floor(byteCount);\n if (ExpoCrypto.getRandomValues) {\n const byteArray = new Uint8Array(validByteCount);\n ExpoCrypto.getRandomValues(byteArray);\n return byteArray;\n } else {\n throw new UnavailabilityError('expo-crypto', 'getRandomBytesAsync');\n }\n}\n\nfunction assertByteCount(value: any, methodName: string): void {\n if (\n typeof value !== 'number' ||\n isNaN(value) ||\n Math.floor(value) < 0 ||\n Math.floor(value) > 1024\n ) {\n throw new TypeError(\n `expo-crypto: ${methodName}(${value}) expected a valid number from range 0...1024`\n );\n }\n}\n\nfunction assertAlgorithm(algorithm: CryptoDigestAlgorithm): void {\n if (!Object.values(CryptoDigestAlgorithm).includes(algorithm)) {\n throw new CryptoError(\n `Invalid algorithm provided. Expected one of: CryptoDigestAlgorithm.${Object.keys(\n CryptoDigestAlgorithm\n ).join(', AlgCryptoDigestAlgorithmorithm.')}`\n );\n }\n}\n\nfunction assertData(data: string): void {\n if (typeof data !== 'string') {\n throw new CryptoError(`Invalid data provided. Expected a string.`);\n }\n}\n\nfunction assertEncoding(encoding: CryptoEncoding): void {\n if (!Object.values(CryptoEncoding).includes(encoding)) {\n throw new CryptoError(\n `Invalid encoding provided. Expected one of: CryptoEncoding.${Object.keys(\n CryptoEncoding\n ).join(', CryptoEncoding.')}`\n );\n }\n}\n\n// @needsAudit\n/**\n * The `digestStringAsync()` method of `Crypto` generates a digest of the supplied `data` string with the provided digest `algorithm`.\n * A digest is a short fixed-length value derived from some variable-length input. **Cryptographic digests** should exhibit _collision-resistance_,\n * meaning that it's very difficult to generate multiple inputs that have equal digest values.\n * You can specify the returned string format as one of `CryptoEncoding`. By default, the resolved value will be formatted as a `HEX` string.\n * On web, this method can only be called from a secure origin (HTTPS) otherwise, an error will be thrown.\n *\n * @param algorithm The cryptographic hash function to use to transform a block of data into a fixed-size output.\n * @param data The value that will be used to generate a digest.\n * @param options Format of the digest string. Defaults to: `CryptoDigestOptions.HEX`.\n * @return Return a Promise which fulfills with a value representing the hashed input.\n *\n * @example\n * ```ts\n * const digest = await Crypto.digestStringAsync(\n * Crypto.CryptoDigestAlgorithm.SHA512,\n * '🥓 Easy to Digest! 💙'\n * );\n * ```\n */\nexport async function digestStringAsync(\n algorithm: CryptoDigestAlgorithm,\n data: string,\n options: CryptoDigestOptions = { encoding: CryptoEncoding.HEX }\n): Promise<Digest> {\n if (!ExpoCrypto.digestStringAsync) {\n throw new UnavailabilityError('expo-crypto', 'digestStringAsync');\n }\n\n assertAlgorithm(algorithm);\n assertData(data);\n assertEncoding(options.encoding);\n\n return await ExpoCrypto.digestStringAsync(algorithm, data, options);\n}\n\n/**\n * The `getRandomValues()` method of `Crypto` fills a provided `TypedArray` with cryptographically secure random values.\n *\n * @param typedArray An integer based [`TypedArray`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray) to fill with cryptographically secure random values. It modifies the input array in place.\n * @return The input array filled with cryptographically secure random values.\n *\n * @example\n * ```ts\n * const byteArray = new Uint8Array(16);\n * Crypto.getRandomValues(byteArray);\n * console.log('Your lucky bytes: ' + byteArray);\n * ```\n */\nexport function getRandomValues<T extends IntBasedTypedArray | UintBasedTypedArray>(\n typedArray: T\n): T {\n ExpoCrypto.getRandomValues(typedArray);\n return typedArray;\n}\n\n/**\n * The `randomUUID()` method returns a unique identifier based on the V4 UUID spec (RFC4122).\n * It uses cryptographically secure random values to generate the UUID.\n *\n * @return A string containing a newly generated UUIDv4 identifier\n * @example\n * ```ts\n * const UUID = Crypto.randomUUID();\n * console.log('Your UUID: ' + UUID);\n * ```\n */\nexport function randomUUID(): string {\n return ExpoCrypto.randomUUID();\n}\n\nconst digestLengths = {\n [CryptoDigestAlgorithm.SHA1]: 20,\n [CryptoDigestAlgorithm.SHA256]: 32,\n [CryptoDigestAlgorithm.SHA384]: 48,\n [CryptoDigestAlgorithm.SHA512]: 64,\n [CryptoDigestAlgorithm.MD2]: 16,\n [CryptoDigestAlgorithm.MD4]: 16,\n [CryptoDigestAlgorithm.MD5]: 16,\n};\n\n/**\n * The `digest()` method of `Crypto` generates a digest of the supplied `TypedArray` of bytes `data` with the provided digest `algorithm`.\n * A digest is a short fixed-length value derived from some variable-length input. **Cryptographic digests** should exhibit _collision-resistance_,\n * meaning that it's very difficult to generate multiple inputs that have equal digest values.\n * On web, this method can only be called from a secure origin (HTTPS) otherwise, an error will be thrown.\n *\n * @param algorithm The cryptographic hash function to use to transform a block of data into a fixed-size output.\n * @param data The value that will be used to generate a digest.\n * @return A Promise which fulfills with an ArrayBuffer representing the hashed input.\n * @example\n * ```ts\n * const array = new Uint8Array([1, 2, 3, 4, 5]);\n * const digest = await Crypto.digest(Crypto.CryptoDigestAlgorithm.SHA512, array);\n * console.log('Your digest: ' + digest);\n * ```\n */\nexport function digest(algorithm: CryptoDigestAlgorithm, data: BufferSource): Promise<ArrayBuffer> {\n return new Promise((resolve, reject) => {\n try {\n if (typeof ExpoCrypto.digestAsync === 'function') {\n resolve(ExpoCrypto.digestAsync(algorithm, data));\n } else {\n const output = new Uint8Array(digestLengths[algorithm]);\n ExpoCrypto.digest(algorithm, output, data);\n resolve(output.buffer);\n }\n } catch (error) {\n reject(error);\n }\n });\n}\n"]}
1
+ {"version":3,"file":"Crypto.js","sourceRoot":"","sources":["../src/Crypto.ts"],"names":[],"mappings":"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","sourcesContent":["import { UnavailabilityError, UintBasedTypedArray, IntBasedTypedArray } from 'expo-modules-core';\n\nimport { CryptoDigestAlgorithm, CryptoEncoding, CryptoDigestOptions, Digest } from './Crypto.types';\nimport ExpoCrypto from './ExpoCrypto';\n\ndeclare const global: any;\n\nexport * from './Crypto.types';\nexport * from './aes';\n\nclass CryptoError extends TypeError {\n code = 'ERR_CRYPTO';\n\n constructor(message: string) {\n super(`expo-crypto: ${message}`);\n }\n}\n\n// @needsAudit\n/**\n * Generates completely random bytes using native implementations. The `byteCount` property\n * is a `number` indicating the number of bytes to generate in the form of a `Uint8Array`.\n * Falls back to `Math.random` during development to prevent issues with React Native Debugger.\n * @param byteCount - A number within the range from `0` to `1024`. Anything else will throw a `TypeError`.\n * @return An array of random bytes with the same length as the `byteCount`.\n */\nexport function getRandomBytes(byteCount: number): Uint8Array {\n assertByteCount(byteCount, 'getRandomBytes');\n const validByteCount = Math.floor(byteCount);\n if (__DEV__) {\n if (!global.nativeCallSyncHook || global.__REMOTEDEV__) {\n // remote javascript debugging is enabled\n const array = new Uint8Array(validByteCount);\n for (let i = 0; i < validByteCount; i++) {\n array[i] = Math.floor(Math.random() * 256);\n }\n return array;\n }\n }\n if (ExpoCrypto.getRandomValues) {\n const byteArray = new Uint8Array(validByteCount);\n ExpoCrypto.getRandomValues(byteArray);\n return byteArray;\n } else {\n throw new UnavailabilityError('expo-crypto', 'getRandomBytes');\n }\n}\n\n// @needsAudit\n/**\n * Generates completely random bytes using native implementations. The `byteCount` property\n * is a `number` indicating the number of bytes to generate in the form of a `Uint8Array`.\n * @param byteCount - A number within the range from `0` to `1024`. Anything else will throw a `TypeError`.\n * @return A promise that fulfills with an array of random bytes with the same length as the `byteCount`.\n */\nexport async function getRandomBytesAsync(byteCount: number): Promise<Uint8Array> {\n assertByteCount(byteCount, 'getRandomBytesAsync');\n const validByteCount = Math.floor(byteCount);\n if (ExpoCrypto.getRandomValues) {\n const byteArray = new Uint8Array(validByteCount);\n ExpoCrypto.getRandomValues(byteArray);\n return byteArray;\n } else {\n throw new UnavailabilityError('expo-crypto', 'getRandomBytesAsync');\n }\n}\n\nfunction assertByteCount(value: any, methodName: string): void {\n if (\n typeof value !== 'number' ||\n isNaN(value) ||\n Math.floor(value) < 0 ||\n Math.floor(value) > 1024\n ) {\n throw new TypeError(\n `expo-crypto: ${methodName}(${value}) expected a valid number from range 0...1024`\n );\n }\n}\n\nfunction assertAlgorithm(algorithm: CryptoDigestAlgorithm): void {\n if (!Object.values(CryptoDigestAlgorithm).includes(algorithm)) {\n throw new CryptoError(\n `Invalid algorithm provided. Expected one of: CryptoDigestAlgorithm.${Object.keys(\n CryptoDigestAlgorithm\n ).join(', AlgCryptoDigestAlgorithmorithm.')}`\n );\n }\n}\n\nfunction assertData(data: string): void {\n if (typeof data !== 'string') {\n throw new CryptoError(`Invalid data provided. Expected a string.`);\n }\n}\n\nfunction assertEncoding(encoding: CryptoEncoding): void {\n if (!Object.values(CryptoEncoding).includes(encoding)) {\n throw new CryptoError(\n `Invalid encoding provided. Expected one of: CryptoEncoding.${Object.keys(\n CryptoEncoding\n ).join(', CryptoEncoding.')}`\n );\n }\n}\n\n// @needsAudit\n/**\n * The `digestStringAsync()` method of `Crypto` generates a digest of the supplied `data` string with the provided digest `algorithm`.\n * A digest is a short fixed-length value derived from some variable-length input. **Cryptographic digests** should exhibit _collision-resistance_,\n * meaning that it's very difficult to generate multiple inputs that have equal digest values.\n * You can specify the returned string format as one of `CryptoEncoding`. By default, the resolved value will be formatted as a `HEX` string.\n * On web, this method can only be called from a secure origin (HTTPS) otherwise, an error will be thrown.\n *\n * @param algorithm The cryptographic hash function to use to transform a block of data into a fixed-size output.\n * @param data The value that will be used to generate a digest.\n * @param options Format of the digest string. Defaults to: `CryptoDigestOptions.HEX`.\n * @return Return a Promise which fulfills with a value representing the hashed input.\n *\n * @example\n * ```ts\n * const digest = await Crypto.digestStringAsync(\n * Crypto.CryptoDigestAlgorithm.SHA512,\n * '🥓 Easy to Digest! 💙'\n * );\n * ```\n */\nexport async function digestStringAsync(\n algorithm: CryptoDigestAlgorithm,\n data: string,\n options: CryptoDigestOptions = { encoding: CryptoEncoding.HEX }\n): Promise<Digest> {\n if (!ExpoCrypto.digestStringAsync) {\n throw new UnavailabilityError('expo-crypto', 'digestStringAsync');\n }\n\n assertAlgorithm(algorithm);\n assertData(data);\n assertEncoding(options.encoding);\n\n return await ExpoCrypto.digestStringAsync(algorithm, data, options);\n}\n\n/**\n * The `getRandomValues()` method of `Crypto` fills a provided `TypedArray` with cryptographically secure random values.\n *\n * @param typedArray An integer based [`TypedArray`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray) to fill with cryptographically secure random values. It modifies the input array in place.\n * @return The input array filled with cryptographically secure random values.\n *\n * @example\n * ```ts\n * const byteArray = new Uint8Array(16);\n * Crypto.getRandomValues(byteArray);\n * console.log('Your lucky bytes: ' + byteArray);\n * ```\n */\nexport function getRandomValues<T extends IntBasedTypedArray | UintBasedTypedArray>(\n typedArray: T\n): T {\n ExpoCrypto.getRandomValues(typedArray);\n return typedArray;\n}\n\n/**\n * The `randomUUID()` method returns a unique identifier based on the V4 UUID spec (RFC4122).\n * It uses cryptographically secure random values to generate the UUID.\n *\n * @return A string containing a newly generated UUIDv4 identifier\n * @example\n * ```ts\n * const UUID = Crypto.randomUUID();\n * console.log('Your UUID: ' + UUID);\n * ```\n */\nexport function randomUUID(): string {\n return ExpoCrypto.randomUUID();\n}\n\nconst digestLengths = {\n [CryptoDigestAlgorithm.SHA1]: 20,\n [CryptoDigestAlgorithm.SHA256]: 32,\n [CryptoDigestAlgorithm.SHA384]: 48,\n [CryptoDigestAlgorithm.SHA512]: 64,\n [CryptoDigestAlgorithm.MD2]: 16,\n [CryptoDigestAlgorithm.MD4]: 16,\n [CryptoDigestAlgorithm.MD5]: 16,\n};\n\n/**\n * The `digest()` method of `Crypto` generates a digest of the supplied `TypedArray` of bytes `data` with the provided digest `algorithm`.\n * A digest is a short fixed-length value derived from some variable-length input. **Cryptographic digests** should exhibit _collision-resistance_,\n * meaning that it's very difficult to generate multiple inputs that have equal digest values.\n * On web, this method can only be called from a secure origin (HTTPS) otherwise, an error will be thrown.\n *\n * @param algorithm The cryptographic hash function to use to transform a block of data into a fixed-size output.\n * @param data The value that will be used to generate a digest.\n * @return A Promise which fulfills with an ArrayBuffer representing the hashed input.\n * @example\n * ```ts\n * const array = new Uint8Array([1, 2, 3, 4, 5]);\n * const digest = await Crypto.digest(Crypto.CryptoDigestAlgorithm.SHA512, array);\n * console.log('Your digest: ' + digest);\n * ```\n */\nexport function digest(algorithm: CryptoDigestAlgorithm, data: BufferSource): Promise<ArrayBuffer> {\n return new Promise((resolve, reject) => {\n try {\n if (typeof ExpoCrypto.digestAsync === 'function') {\n resolve(ExpoCrypto.digestAsync(algorithm, data));\n } else {\n const output = new Uint8Array(digestLengths[algorithm]);\n ExpoCrypto.digest(algorithm, output, data);\n resolve(output.buffer);\n }\n } catch (error) {\n reject(error);\n }\n });\n}\n"]}