Skip to content

Commit 3eaf849

Browse files
authored
feat: Add Post-Quantum Cryptography Support (ML-DSA) (#842)
1 parent 7fe1a04 commit 3eaf849

35 files changed

+1465
-6458
lines changed

.gitmodules

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
11
[submodule "packages/react-native-quick-crypto/deps/blake3"]
22
path = packages/react-native-quick-crypto/deps/blake3
33
url = https://github.com/BLAKE3-team/BLAKE3.git
4+
[submodule "packages/react-native-quick-crypto/deps/ncrypto"]
5+
path = packages/react-native-quick-crypto/deps/ncrypto
6+
url = https://github.com/boorad/ncrypto.git
7+
branch = fix/use-BN_GENCB_get_arg

docs/implementation-coverage.md

Lines changed: 88 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,17 @@
11
# Implementation Coverage - NodeJS
22
This document attempts to describe the implementation status of Crypto APIs/Interfaces from Node.js in the `react-native-quick-crypto` library.
33

4-
> Note: This is the status for version 1.x and higher. For version `0.x` see [this document](https://github.com/margelo/react-native-quick-crypto/blob/0.x/docs/implementation-coverage.md) and the [0.x branch](https://github.com/margelo/react-native-quick-crypto/tree/0.x).
5-
64
* ` ` - not implemented in Node
75
* ❌ - implemented in Node, not RNQC
86
* ✅ - implemented in Node and RNQC
7+
* 🚧 - work in progress
8+
9+
## Post-Quantum Cryptography (PQC)
10+
11+
- **ML-DSA** (Module Lattice Digital Signature Algorithm, FIPS 204) - ML-DSA-44, ML-DSA-65, ML-DSA-87
12+
- **ML-KEM** (Module Lattice Key Encapsulation Mechanism, FIPS 203) - ML-KEM-512, ML-KEM-768, ML-KEM-1024
13+
14+
These algorithms provide quantum-resistant cryptography.
915

1016
# `Crypto`
1117

@@ -147,13 +153,11 @@ This document attempts to describe the implementation status of Crypto APIs/Inte
147153
*`crypto.secureHeapUsed()`
148154
*`crypto.setEngine(engine[, flags])`
149155
*`crypto.setFips(bool)`
150-
* 🚧 `crypto.sign(algorithm, data, key[, callback])`
156+
* `crypto.sign(algorithm, data, key[, callback])`
151157
* 🚧 `crypto.subtle` (see below)
152158
*`crypto.timingSafeEqual(a, b)`
153-
* 🚧 `crypto.verify(algorithm, data, key, signature[, callback])`
154-
*`crypto.webcrypto` (see below)
155-
156-
🚧 Details below still a work in progress 🚧
159+
*`crypto.verify(algorithm, data, key, signature[, callback])`
160+
* 🚧 `crypto.webcrypto` (see below)
157161

158162
## `crypto.diffieHellman`
159163
| type | Status |
@@ -204,22 +208,22 @@ This document attempts to describe the implementation status of Crypto APIs/Inte
204208
## `crypto.sign`
205209
| Algorithm | Status |
206210
| --------- | :----: |
207-
| `RSASSA-PKCS1-v1_5` | |
208-
| `RSA-PSS` | |
209-
| `ECDSA` | |
211+
| `RSASSA-PKCS1-v1_5` | |
212+
| `RSA-PSS` | |
213+
| `ECDSA` | |
210214
| `Ed25519` ||
211215
| `Ed448` ||
212-
| `HMAC` | |
216+
| `HMAC` | |
213217

214218
## `crypto.verify`
215219
| Algorithm | Status |
216220
| --------- | :----: |
217-
| `RSASSA-PKCS1-v1_5` | |
218-
| `RSA-PSS` | |
219-
| `ECDSA` | |
221+
| `RSASSA-PKCS1-v1_5` | |
222+
| `RSA-PSS` | |
223+
| `ECDSA` | |
220224
| `Ed25519` ||
221225
| `Ed448` ||
222-
| `HMAC` | |
226+
| `HMAC` | |
223227

224228
# `WebCrypto`
225229

@@ -240,7 +244,7 @@ This document attempts to describe the implementation status of Crypto APIs/Inte
240244

241245
# `SubtleCrypto`
242246

243-
* 🚧 Class: `SubtleCrypto`
247+
* Class: `SubtleCrypto`
244248
* ❌ static `supports(operation, algorithm[, lengthOrAdditionalAlgorithm])`
245249
*`subtle.decapsulateBits(decapsulationAlgorithm, decapsulationKey, ciphertext)`
246250
*`subtle.decapsulateKey(decapsulationAlgorithm, decapsulationKey, ciphertext, sharedKeyAlgorithm, extractable, usages)`
@@ -255,9 +259,9 @@ This document attempts to describe the implementation status of Crypto APIs/Inte
255259
* 🚧 `subtle.generateKey(algorithm, extractable, keyUsages)`
256260
*`subtle.getPublicKey(key, keyUsages)`
257261
* 🚧 `subtle.importKey(format, keyData, algorithm, extractable, keyUsages)`
258-
* 🚧 `subtle.sign(algorithm, key, data)`
262+
* `subtle.sign(algorithm, key, data)`
259263
*`subtle.unwrapKey(format, wrappedKey, unwrappingKey, unwrapAlgo, unwrappedKeyAlgo, extractable, keyUsages)`
260-
* 🚧 `subtle.verify(algorithm, key, signature, data)`
264+
* `subtle.verify(algorithm, key, signature, data)`
261265
*`subtle.wrapKey(format, key, wrappingKey, wrapAlgo)`
262266

263267
## `subtle.decrypt`
@@ -311,27 +315,27 @@ This document attempts to describe the implementation status of Crypto APIs/Inte
311315

312316
## `subtle.exportKey`
313317
| Key Type | `spki` | `pkcs8` | `jwk` | `raw` | `raw-secret` | `raw-public` | `raw-seed` |
314-
| ------------------- | :----: | :-----: | :---: | :---: | :---: | :---: | :---: |
315-
| `AES-CBC` | | |||| | |
316-
| `AES-CTR` | | |||| | |
317-
| `AES-GCM` | | |||| | |
318-
| `AES-KW` | | |||| | |
319-
| `AES-OCB` | | || || | |
320-
| `ChaCha20-Poly1305` | | || || | |
321-
| `ECDH` ||||| || |
322-
| `ECDSA` ||||| || |
323-
| `Ed25519` | |||| || |
324-
| `Ed448` | |||| || |
325-
| `HMAC` | | |||| | |
326-
| `ML-DSA-44` | ||| | || |
327-
| `ML-DSA-65` | ||| | || |
328-
| `ML-DSA-87` | ||| | || |
329-
| `ML-KEM-512` ||| | | |||
330-
| `ML-KEM-768` ||| | | |||
331-
| `ML-KEM-1024` ||| | | |||
332-
| `RSA-OAEP` |||| | | | |
333-
| `RSA-PSS` |||| | | | |
334-
| `RSASSA-PKCS1-v1_5` |||| | | | |
318+
| ------------------- | :----: | :-----: | :---: | :---: | :----------: | :----------: | :--------: |
319+
| `AES-CBC` | | | | | | | |
320+
| `AES-CTR` | | | | | | | |
321+
| `AES-GCM` | | | | | | | |
322+
| `AES-KW` | | | | | | | |
323+
| `AES-OCB` | | | | | | | |
324+
| `ChaCha20-Poly1305` | | | | | | | |
325+
| `ECDH` | | | | | | | |
326+
| `ECDSA` | | | | | | | |
327+
| `Ed25519` | || | | | | |
328+
| `Ed448` | || | | | | |
329+
| `HMAC` | | | | | | | |
330+
| `ML-DSA-44` | ||| | || |
331+
| `ML-DSA-65` | ||| | || |
332+
| `ML-DSA-87` | ||| | || |
333+
| `ML-KEM-512` | | | | | | | |
334+
| `ML-KEM-768` | | | | | | | |
335+
| `ML-KEM-1024` | | | | | | | |
336+
| `RSA-OAEP` | | | | | | | |
337+
| `RSA-PSS` | | | | | | | |
338+
| `RSASSA-PKCS1-v1_5` | | | | | | | |
335339

336340
* ` ` - not implemented in Node
337341
* ❌ - implemented in Node, not RNQC
@@ -346,9 +350,9 @@ This document attempts to describe the implementation status of Crypto APIs/Inte
346350
| `ECDSA` ||
347351
| `Ed25519` ||
348352
| `Ed448` ||
349-
| `ML-DSA-44` | |
350-
| `ML-DSA-65` | |
351-
| `ML-DSA-87` | |
353+
| `ML-DSA-44` | |
354+
| `ML-DSA-65` | |
355+
| `ML-DSA-87` | |
352356
| `ML-KEM-512` ||
353357
| `ML-KEM-768` ||
354358
| `ML-KEM-1024` ||
@@ -367,48 +371,48 @@ This document attempts to describe the implementation status of Crypto APIs/Inte
367371
| `AES-KW` ||
368372
| `AES-OCB` ||
369373
| `ChaCha20-Poly1305` ||
370-
| `HMAC` | |
374+
| `HMAC` | |
371375

372376
## `subtle.importKey`
373377
| Key Type | `spki` | `pkcs8` | `jwk` | `raw` | `raw-secret` | `raw-public` | `raw-seed` |
374-
| ------------------- | :---: | :---: | :---: | :---: | :---: | :---: | :---: |
375-
| `AES-CBC` | | |||| | |
376-
| `AES-CTR` | | |||| | |
377-
| `AES-GCM` | | |||| | |
378-
| `AES-KW` | | |||| | |
379-
| `AES-OCB` | | || || | |
380-
| `ChaCha20-Poly1305` | | || || | |
381-
| `ECDH` ||||| || |
382-
| `ECDSA` ||||| || |
383-
| `Ed25519` | |||| || |
384-
| `Ed448` | |||| || |
385-
| `HDKF` | | | ||| | |
386-
| `HMAC` | | |||| | |
387-
| `ML-DSA-44` | ||| | || |
388-
| `ML-DSA-65` | ||| | || |
389-
| `ML-DSA-87` | ||| | || |
390-
| `ML-KEM-512` ||| | | |||
391-
| `ML-KEM-768` ||| | | |||
392-
| `ML-KEM-1024` ||| | | |||
393-
| `PBKDF2` | | | ||| | |
394-
| `RSA-OAEP` |||| | | | |
395-
| `RSA-PSS` |||| | | | |
396-
| `RSASSA-PKCS1-v1_5` |||| | | | |
397-
| `X25519` ||||| || |
398-
| `X448` ||||| || |
378+
| ------------------- | :----: | :-----: | :---: | :---: | :----------: | :----------: | :--------: |
379+
| `AES-CBC` | | | | | | | |
380+
| `AES-CTR` | | | | | | | |
381+
| `AES-GCM` | | | | | | | |
382+
| `AES-KW` | | | | | | | |
383+
| `AES-OCB` | | | | | | | |
384+
| `ChaCha20-Poly1305` | | | | | | | |
385+
| `ECDH` | | | | | | | |
386+
| `ECDSA` | | | | | | | |
387+
| `Ed25519` | || | | | | |
388+
| `Ed448` | || | | | | |
389+
| `HKDF` | | | | | | | |
390+
| `HMAC` | | | | | | | |
391+
| `ML-DSA-44` | ||| | || |
392+
| `ML-DSA-65` | ||| | || |
393+
| `ML-DSA-87` | ||| | || |
394+
| `ML-KEM-512` | | | | | | | |
395+
| `ML-KEM-768` | | | | | | | |
396+
| `ML-KEM-1024` | | | | | | | |
397+
| `PBKDF2` | | | | | | | |
398+
| `RSA-OAEP` | || | | | | |
399+
| `RSA-PSS` | || | | | | |
400+
| `RSASSA-PKCS1-v1_5` | || | | | | |
401+
| `X25519` | | | | | | | |
402+
| `X448` | | | | | | | |
399403

400404
## `subtle.sign`
401405
| Algorithm | Status |
402406
| --------- | :----: |
403407
| `ECDSA` ||
404-
| `Ed25519` | |
405-
| `Ed448` | |
406-
| `HMAC` | |
407-
| `ML-DSA-44` | |
408-
| `ML-DSA-65` | |
409-
| `ML-DSA-87` | |
410-
| `RSA-PSS` | |
411-
| `RSASSA-PKCS1-v1_5` | |
408+
| `Ed25519` | |
409+
| `Ed448` | |
410+
| `HMAC` | |
411+
| `ML-DSA-44` | |
412+
| `ML-DSA-65` | |
413+
| `ML-DSA-87` | |
414+
| `RSA-PSS` | |
415+
| `RSASSA-PKCS1-v1_5` | |
412416

413417
## `subtle.unwrapKey`
414418

@@ -453,14 +457,14 @@ This document attempts to describe the implementation status of Crypto APIs/Inte
453457
| Algorithm | Status |
454458
| --------- | :----: |
455459
| `ECDSA` ||
456-
| `Ed25519` | |
457-
| `Ed448` | |
458-
| `HMAC` | |
459-
| `ML-DSA-44` | |
460-
| `ML-DSA-65` | |
461-
| `ML-DSA-87` | |
462-
| `RSA-PSS` | |
463-
| `RSASSA-PKCS1-v1_5` | |
460+
| `Ed25519` | |
461+
| `Ed448` | |
462+
| `HMAC` | |
463+
| `ML-DSA-44` | |
464+
| `ML-DSA-65` | |
465+
| `ML-DSA-87` | |
466+
| `RSA-PSS` | |
467+
| `RSASSA-PKCS1-v1_5` | |
464468

465469
## `subtle.wrapKey`
466470

example/ios/Podfile

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,16 +40,16 @@ target 'QuickCryptoExample' do
4040
target.build_configurations.each do |config|
4141
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '16.1'
4242
config.build_settings['CLANG_CXX_LANGUAGE_STANDARD'] = 'c++20'
43-
43+
4444
# Force C++20 for all targets, especially problematic ones
4545
config.build_settings['GCC_C_LANGUAGE_STANDARD'] = 'gnu11'
4646
config.build_settings['CLANG_CXX_LIBRARY'] = 'libc++'
47-
47+
4848
# Remove any conflicting C++ standard flags
4949
config.build_settings.delete('CLANG_CXX_LANGUAGE_STANDARD_OVERRIDE')
5050
end
5151
end
52-
52+
5353
# Specifically target RCT-Folly and other React Native core pods
5454
installer.pods_project.targets.each do |target|
5555
if target.name.include?('Folly') || target.name.include?('React-') || target.name.include?('RCT')
@@ -58,5 +58,48 @@ target 'QuickCryptoExample' do
5858
end
5959
end
6060
end
61+
62+
# Embed OpenSSL.framework from SPM into the app bundle
63+
# SPM frameworks added to Pods project need manual embedding
64+
main_project_path = File.join(installer.sandbox.root.parent, 'QuickCryptoExample.xcodeproj')
65+
main_project = Xcodeproj::Project.open(main_project_path)
66+
app_target = main_project.targets.find { |t| t.name == 'QuickCryptoExample' }
67+
68+
if app_target
69+
embed_phase_name = 'Embed SPM Frameworks (OpenSSL)'
70+
existing_phase = app_target.shell_script_build_phases.find { |p| p.name == embed_phase_name }
71+
72+
unless existing_phase
73+
phase = app_target.new_shell_script_build_phase(embed_phase_name)
74+
phase.shell_script = <<~SCRIPT
75+
# Embed OpenSSL.framework from SPM build into app bundle
76+
# SPM builds the framework to BUILT_PRODUCTS_DIR but doesn't embed it
77+
OPENSSL_FRAMEWORK="${BUILT_PRODUCTS_DIR}/OpenSSL.framework"
78+
79+
if [ -d "$OPENSSL_FRAMEWORK" ]; then
80+
echo "Found OpenSSL.framework at $OPENSSL_FRAMEWORK"
81+
mkdir -p "${BUILT_PRODUCTS_DIR}/${FRAMEWORKS_FOLDER_PATH}"
82+
rsync -av --delete "$OPENSSL_FRAMEWORK" "${BUILT_PRODUCTS_DIR}/${FRAMEWORKS_FOLDER_PATH}/"
83+
84+
# Code sign if required
85+
if [ -n "${EXPANDED_CODE_SIGN_IDENTITY:-}" ] && [ "${CODE_SIGNING_REQUIRED:-}" != "NO" ]; then
86+
/usr/bin/codesign --force --sign "${EXPANDED_CODE_SIGN_IDENTITY}" --preserve-metadata=identifier,entitlements "${BUILT_PRODUCTS_DIR}/${FRAMEWORKS_FOLDER_PATH}/OpenSSL.framework"
87+
fi
88+
echo "OpenSSL.framework embedded successfully"
89+
else
90+
echo "warning: OpenSSL.framework not found at $OPENSSL_FRAMEWORK"
91+
fi
92+
SCRIPT
93+
94+
# Move it before the existing embed frameworks phase
95+
embed_pods_phase = app_target.shell_script_build_phases.find { |p| p.name == '[CP] Embed Pods Frameworks' }
96+
if embed_pods_phase
97+
app_target.build_phases.move(phase, app_target.build_phases.index(embed_pods_phase))
98+
end
99+
100+
main_project.save
101+
Pod::UI.puts "[QuickCrypto] Added 'Embed SPM Frameworks (OpenSSL)' build phase"
102+
end
103+
end
61104
end
62105
end

example/ios/Podfile.lock

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ PODS:
3737
- ReactCommon/turbomodule/core
3838
- SocketRocket
3939
- Yoga
40-
- OpenSSL-Universal (3.3.3001)
4140
- QuickCrypto (1.0.0):
4241
- boost
4342
- DoubleConversion
@@ -46,7 +45,6 @@ PODS:
4645
- glog
4746
- hermes-engine
4847
- NitroModules
49-
- OpenSSL-Universal (= 3.3.3001)
5048
- RCT-Folly
5149
- RCT-Folly/Fabric
5250
- RCTRequired
@@ -2605,7 +2603,6 @@ DEPENDENCIES:
26052603

26062604
SPEC REPOS:
26072605
trunk:
2608-
- OpenSSL-Universal
26092606
- SocketRocket
26102607

26112608
EXTERNAL SOURCES:
@@ -2776,8 +2773,7 @@ SPEC CHECKSUMS:
27762773
glog: 5683914934d5b6e4240e497e0f4a3b42d1854183
27772774
hermes-engine: 4f8246b1f6d79f625e0d99472d1f3a71da4d28ca
27782775
NitroModules: 1715fe0e22defd9e2cdd48fb5e0dbfd01af54bec
2779-
OpenSSL-Universal: 6082b0bf950e5636fe0d78def171184e2b3899c2
2780-
QuickCrypto: 4e82c6565ea7b5f9d4c3f0ad3f19b785a676b4cc
2776+
QuickCrypto: fad28b0727d1b6ffecab0fc8e407c14b135cdca0
27812777
RCT-Folly: 846fda9475e61ec7bcbf8a3fe81edfcaeb090669
27822778
RCTDeprecation: c4b9e2fd0ab200e3af72b013ed6113187c607077
27832779
RCTRequired: e97dd5dafc1db8094e63bc5031e0371f092ae92a
@@ -2849,6 +2845,6 @@ SPEC CHECKSUMS:
28492845
SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748
28502846
Yoga: 11c9686a21e2cd82a094a723649d9f4507200fb0
28512847

2852-
PODFILE CHECKSUM: 8bf59f4e86b38489f786b2878e119cdf1824ca75
2848+
PODFILE CHECKSUM: bc958092bb9060694d04c6fcf716262b0549cded
28532849

28542850
COCOAPODS: 1.15.2

0 commit comments

Comments
 (0)