diff --git a/cpp/CPPLINT.cfg b/cpp/CPPLINT.cfg index 0aea5b5..7273452 100644 --- a/cpp/CPPLINT.cfg +++ b/cpp/CPPLINT.cfg @@ -14,4 +14,4 @@ linelength=200 # does not make sense for our project setup since this is not a large cpp codebase. # # Disabled runtime/int because uint64_t didn't work with the Android build -filter=-runtime/references,-legal/copyright,-build/include_subdir,-whitespace/braces,-whitespace/newline,-whitespace/ending_newline,-readability/fn_size,-runtime/int,-whitespace/comments +filter=-runtime/references,-legal/copyright,-build/include_subdir,-whitespace/braces,-whitespace/newline,-whitespace/ending_newline,-readability/fn_size,-runtime/int,-whitespace/comments,-whitespace/indent_namespace diff --git a/cpp/react-native-libsodium.cpp b/cpp/react-native-libsodium.cpp index ddc22c2..a97e74b 100644 --- a/cpp/react-native-libsodium.cpp +++ b/cpp/react-native-libsodium.cpp @@ -213,6 +213,7 @@ namespace ReactNativeLibsodium jsiRuntime.global().setProperty(jsiRuntime, "jsi_crypto_kdf_hkdf_sha256_BYTES_MAX", static_cast(crypto_kdf_hkdf_sha256_BYTES_MAX)); jsiRuntime.global().setProperty(jsiRuntime, "jsi_crypto_kdf_hkdf_sha256_BYTES_MIN", static_cast(crypto_kdf_hkdf_sha256_BYTES_MIN)); jsiRuntime.global().setProperty(jsiRuntime, "jsi_crypto_kdf_hkdf_sha256_KEYBYTES", static_cast(crypto_kdf_hkdf_sha256_KEYBYTES)); + jsiRuntime.global().setProperty(jsiRuntime, "jsi_crypto_pwhash_ALG_ARGON2ID13", static_cast(crypto_pwhash_ALG_ARGON2ID13)); auto jsi_from_base64_to_arraybuffer = jsi::Function::createFromHostFunction( jsiRuntime, @@ -1196,6 +1197,33 @@ namespace ReactNativeLibsodium jsiRuntime.global().setProperty(jsiRuntime, "jsi_crypto_pwhash", std::move(jsi_crypto_pwhash)); + auto jsi_crypto_sign_ed25519_pk_to_curve25519 = jsi::Function::createFromHostFunction( + jsiRuntime, + jsi::PropNameID::forUtf8(jsiRuntime, "jsi_crypto_sign_ed25519_pk_to_curve25519"), + 1, + [](jsi::Runtime &runtime, const jsi::Value &thisValue, const jsi::Value *arguments, size_t count) -> jsi::Value + { + const std::string functionName = "crypto_sign_ed25519_pk_to_curve25519"; + + std::string publicKeyArgumentName = "publicKey"; + unsigned int publicKeyArgumentPosition = 0; + validateIsArrayBuffer(functionName, runtime, arguments[publicKeyArgumentPosition], publicKeyArgumentName, true); + + auto publicKeyArrayBuffer = arguments[publicKeyArgumentPosition].asObject(runtime).getArrayBuffer(runtime); + + std::vector publicKey(crypto_sign_PUBLICKEYBYTES); + int result = -1; + + result = crypto_sign_ed25519_pk_to_curve25519( + publicKey.data(), + publicKeyArrayBuffer.data(runtime)); + + throwOnBadResult(functionName, runtime, result); + return arrayBufferAsObject(runtime, publicKey); + }); + + jsiRuntime.global().setProperty(jsiRuntime, "jsi_crypto_sign_ed25519_pk_to_curve25519", std::move(jsi_crypto_sign_ed25519_pk_to_curve25519)); + auto jsi_crypto_kdf_derive_from_key = jsi::Function::createFromHostFunction( jsiRuntime, jsi::PropNameID::forUtf8(jsiRuntime, "jsi_crypto_kdf_derive_from_key"), diff --git a/example/src/components/TestResults.tsx b/example/src/components/TestResults.tsx index b38c3b4..806ca22 100644 --- a/example/src/components/TestResults.tsx +++ b/example/src/components/TestResults.tsx @@ -18,6 +18,7 @@ import '../tests/crypto_generichash_test'; import '../tests/crypto_kdf_derive_from_key_test'; import '../tests/crypto_kdf_keygen_test'; import '../tests/crypto_pwhash_test'; +import '../tests/crypto_sign_ed25519_pk_to_curve25519_test'; import '../tests/crypto_secretbox_easy_test'; import '../tests/crypto_secretbox_keygen_test'; import '../tests/crypto_secretbox_open_easy_test'; diff --git a/example/src/tests/constants_test.ts b/example/src/tests/constants_test.ts index f53f83c..5110369 100644 --- a/example/src/tests/constants_test.ts +++ b/example/src/tests/constants_test.ts @@ -13,6 +13,7 @@ import { crypto_secretbox_KEYBYTES, crypto_secretbox_NONCEBYTES, crypto_sign_SEEDBYTES, + crypto_pwhash_ALG_ARGON2ID13, } from 'react-native-libsodium'; import { expect, test } from '../utils/testRunner'; @@ -31,4 +32,5 @@ test('constants', () => { expect(_unstable_crypto_kdf_hkdf_sha256_KEYBYTES).toEqual(32); expect(_unstable_crypto_kdf_hkdf_sha256_BYTES_MIN).toEqual(0); expect(_unstable_crypto_kdf_hkdf_sha256_BYTES_MAX).toEqual(8160); + expect(crypto_pwhash_ALG_ARGON2ID13).toEqual(2); }); diff --git a/example/src/tests/crypto_sign_ed25519_pk_to_curve25519_test.ts b/example/src/tests/crypto_sign_ed25519_pk_to_curve25519_test.ts new file mode 100644 index 0000000..be2e110 --- /dev/null +++ b/example/src/tests/crypto_sign_ed25519_pk_to_curve25519_test.ts @@ -0,0 +1,21 @@ +import { crypto_sign_ed25519_pk_to_curve25519 } from 'react-native-libsodium'; +import { isEqualUint8Array } from '../utils/isEqualUint8Array'; +import { expect, test } from '../utils/testRunner'; + +test('crypto_sign_ed25519_pk_to_curve25519', () => { + const publicKey = new Uint8Array([ + 38, 187, 152, 175, 122, 23, 12, 100, 83, 68, 221, 23, 158, 24, 170, 13, 234, + 4, 53, 212, 90, 147, 161, 67, 243, 45, 175, 177, 59, 239, 38, 65, + ]); + + expect( + isEqualUint8Array( + crypto_sign_ed25519_pk_to_curve25519(publicKey), + new Uint8Array([ + 1, 123, 90, 189, 215, 54, 174, 97, 2, 183, 14, 184, 18, 115, 105, 142, + 141, 119, 109, 227, 130, 213, 21, 35, 162, 131, 125, 189, 213, 158, 9, + 17, + ]) + ) + ).toBe(true); +}); diff --git a/src/lib.native.ts b/src/lib.native.ts index 7eb0699..134678d 100644 --- a/src/lib.native.ts +++ b/src/lib.native.ts @@ -51,6 +51,7 @@ declare global { var jsi_crypto_kdf_hkdf_sha256_BYTES_MAX: number; var jsi_crypto_kdf_hkdf_sha256_BYTES_MIN: number; var jsi_crypto_kdf_hkdf_sha256_KEYBYTES: number; + var jsi_crypto_pwhash_ALG_ARGON2ID13: number; function jsi_crypto_auth( message: string | ArrayBuffer, @@ -145,6 +146,9 @@ declare global { memLimit: number, algorithm: number ): ArrayBuffer; + function jsi_crypto_sign_ed25519_pk_to_curve25519( + publicKey: ArrayBuffer + ): ArrayBuffer; function jsi_crypto_kdf_derive_from_key( subkeyLength: number, subkeyId: number, @@ -221,6 +225,8 @@ export const _unstable_crypto_kdf_hkdf_sha256_BYTES_MIN = global.jsi_crypto_kdf_hkdf_sha256_BYTES_MIN; export const _unstable_crypto_kdf_hkdf_sha256_KEYBYTES = global.jsi_crypto_kdf_hkdf_sha256_KEYBYTES; +export const crypto_pwhash_ALG_ARGON2ID13 = + global.jsi_crypto_pwhash_ALG_ARGON2ID13; export const from_base64 = ( input: string, @@ -685,6 +691,15 @@ export function crypto_pwhash( ); return convertToOutputFormat(result, outputFormat); } +export function crypto_sign_ed25519_pk_to_curve25519( + publicKey: Uint8Array, + outputFormat?: Uint8ArrayOutputFormat | null +) { + const result = global.jsi_crypto_sign_ed25519_pk_to_curve25519( + publicKey.buffer + ); + return convertToOutputFormat(result, outputFormat); +} export function crypto_kdf_derive_from_key( subkey_len: number, @@ -857,12 +872,14 @@ export default { crypto_kdf_KEYBYTES, crypto_kdf_keygen, crypto_pwhash, + crypto_sign_ed25519_pk_to_curve25519, crypto_pwhash_ALG_DEFAULT, crypto_pwhash_BYTES_MAX, crypto_pwhash_BYTES_MIN, crypto_pwhash_MEMLIMIT_INTERACTIVE, crypto_pwhash_OPSLIMIT_INTERACTIVE, crypto_pwhash_SALTBYTES, + crypto_pwhash_ALG_ARGON2ID13, crypto_secretbox_easy, crypto_secretbox_KEYBYTES, crypto_secretbox_keygen,