Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add ciphers #573

Draft
wants to merge 8 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ QuickCrypto can be used as a drop-in replacement for your Web3/Crypto apps to sp

| Version | RN Architecture | Modules |
| ------- | ------ | ------- |
| `1.x` | new [->](https://github.com/reactwg/react-native-new-architecture/blob/main/docs/enable-apps.md) | Nitro Modules [->](https://github.com/margelo/react-native-nitro) |
| `1.x` | new [->](https://github.com/reactwg/react-native-new-architecture/blob/main/docs/enable-apps.md) | Nitro Modules [->](https://github.com/mrousavy/nitro) |
| `0.x` | old | Bridge & JSI |

## Benchmarks
Expand Down
Binary file modified bun.lockb
Binary file not shown.
4 changes: 2 additions & 2 deletions example/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,10 @@
"events": "3.3.0",
"react": "18.3.1",
"react-native": "0.76.1",
"react-native-bouncy-checkbox": "4.0.1",
"react-native-bouncy-checkbox": "4.1.2",
"react-native-nitro-modules": "0.18.2",
"react-native-quick-base64": "2.1.2",
"react-native-quick-crypto": "1.0.0-beta.9",
"react-native-quick-crypto": "workspace:*",
"react-native-safe-area-context": "4.14.0",
"react-native-screens": "3.35.0",
"react-native-vector-icons": "^10.1.0",
Expand Down
3 changes: 3 additions & 0 deletions example/src/hooks/useTestsList.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,20 @@ import { useState, useCallback } from 'react';
import type { TestSuites } from '../types/tests';
import { TestsContext } from '../tests/util';

import '../tests/cipher/cipher_tests';
import '../tests/ed25519/ed25519_tests';
import '../tests/pbkdf2/pbkdf2_tests';
import '../tests/random/random_tests';
// import '../tests/HmacTests/HmacTests';
// import '../tests/HashTests/HashTests';

// import '../tests/CipherTests/CipherTestFirst';
// import '../tests/CipherTests/CipherTestSecond';
// import '../tests/CipherTests/PublicCipherTests';
// import '../tests/CipherTests/test398';
// import '../tests/CipherTests/generateKey';
// import '../tests/CipherTests/GenerateKeyPairTests';

// import '../tests/ConstantsTests/ConstantsTests';
// import '../tests/SignTests/SignTests';
// import '../tests/SmokeTests/bundlerTests';
Expand Down
93 changes: 0 additions & 93 deletions example/src/hooks/useTestsRun.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,96 +84,3 @@ const run = (
stats.duration = stats.end.valueOf() - stats.start.valueOf();
return stats;
};

// const run = (
// addTestResult: (testResult: TestResult) => void,
// tests: Suites = {},
// ) => {
// const {
// EVENT_RUN_BEGIN,
// EVENT_RUN_END,
// EVENT_TEST_FAIL,
// EVENT_TEST_PASS,
// EVENT_TEST_PENDING,
// EVENT_TEST_END,
// EVENT_SUITE_BEGIN,
// EVENT_SUITE_END,
// } = Mocha.Runner.constants;

// const stats: Stats = { ...defaultStats };

// const runner = new Mocha.Runner(rootSuite);
// runner.stats = stats;

// // enable/disable tests based on checkbox value
// runner.suite.suites.map(s => {
// const suiteName = s.title;
// if (!tests[suiteName]?.value) {
// // console.log(`skipping '${suiteName}' suite`);
// s.tests.map(t => {
// t.skip();
// });
// } else {
// // console.log(`will run '${suiteName}' suite`);
// s.tests.map(t => {
// // @ts-expect-error - not sure why this is erroring
// t.reset();
// });
// }
// });

// let indents = -1;
// const indent = () => Array(indents).join(' ');
// runner
// .once(EVENT_RUN_BEGIN, () => {
// stats.start = new Date();
// })
// .on(EVENT_SUITE_BEGIN, (suite: MochaTypes.Suite) => {
// if (!suite.root) stats.suites++;
// indents++;
// })
// .on(EVENT_SUITE_END, () => {
// indents--;
// })
// .on(EVENT_TEST_PASS, (test: MochaTypes.Runnable) => {
// const name = test.parent?.title || '';
// stats.passes++;
// addTestResult({
// indentation: indents,
// description: test.title,
// suiteName: name,
// type: 'correct',
// });
// console.log(`${indent()}pass: ${test.title}`);
// })
// .on(EVENT_TEST_FAIL, (test: MochaTypes.Runnable, err: Error) => {
// const name = test.parent?.title || '';
// stats.failures++;
// addTestResult({
// indentation: indents,
// description: test.title,
// suiteName: name,
// type: 'incorrect',
// errorMsg: err.message,
// });
// console.log(`${indent()}fail: ${test.title} - error: ${err.message}`);
// })
// .on(EVENT_TEST_PENDING, function () {
// stats.pending++;
// })
// .on(EVENT_TEST_END, function () {
// stats.tests++;
// })
// .once(EVENT_RUN_END, () => {
// stats.end = new Date();
// stats.duration = stats.end.valueOf() - stats.start.valueOf();
// console.log(JSON.stringify(runner.stats, null, 2));
// });

// runner.run();

// return () => {
// console.log('aborting');
// runner.abort();
// };
// };
23 changes: 23 additions & 0 deletions example/src/tests/cipher/cipher_tests.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import {
Cipher,
createCipheriv,
randomFillSync,
} from 'react-native-quick-crypto';
import { expect } from 'chai';
import { test } from '../util';

const SUITE = 'cipher';
const key = 'secret';
const iv = randomFillSync(new Uint8Array(16));

test(SUITE, 'cipher - valid algorithm', async () => {
const cipher = createCipheriv('aes-128-cbc', key, iv, {});
expect(cipher).to.be.instanceOf(Cipher);
});

test(SUITE, 'cipher - invalid algorithm', async () => {
expect(() => {
// @ts-expect-error - testing bad algorithm
createCipheriv('aes-128-boorad', key, iv, {});
}).to.throw(/Invalid Cipher Algorithm: aes-128-boorad/);
});
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"specs": "bun --filter='react-native-quick-crypto' specs",
"bundle-install": "bun --filter='react-native-quick-crypto-example' bundle-install",
"pods": "bun --filter='react-native-quick-crypto-example' pods",
"start": "bun --filter='react-native-quick-crypto-example' start",
"start": "cd example && bun start",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not use --filter flag anymore?

should other commands also be updated?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When I do bun start from top level (not in example folder), the command with --filter rolls through 10 lines and truncates. This way, I see all the history in the terminal. The others don't need to change.

"bootstrap": "bun install && bun pods",
"tsc": "bun --filter='*' typescript",
"lint": "bun --filter='*' lint",
Expand Down
2 changes: 2 additions & 0 deletions packages/react-native-quick-crypto/android/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ set(CMAKE_CXX_STANDARD 20)
add_library(
${PACKAGE_NAME} SHARED
src/main/cpp/cpp-adapter.cpp
../cpp/cipher/HybridCipher.cpp
../cpp/ed25519/HybridEdKeyPair.cpp
../cpp/pbkdf2/HybridPbkdf2.cpp
../cpp/random/HybridRandom.cpp
Expand All @@ -21,6 +22,7 @@ include(${CMAKE_SOURCE_DIR}/../nitrogen/generated/android/QuickCrypto+autolinkin
# local includes
include_directories(
"src/main/cpp"
"../cpp/cipher"
"../cpp/ed25519"
"../cpp/pbkdf2"
"../cpp/random"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.module.model.ReactModuleInfoProvider;
import com.facebook.react.TurboReactPackage;
import com.margelo.nitro.core.HybridObject;
import com.margelo.nitro.core.HybridObjectRegistry;

import java.util.HashMap;
import java.util.function.Supplier;
Expand Down
72 changes: 72 additions & 0 deletions packages/react-native-quick-crypto/cpp/cipher/HybridCipher.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#include <memory>

#include "HybridCipher.hpp"

namespace margelo::nitro::crypto {

std::shared_ptr<ArrayBuffer>
HybridCipher::update(
const std::shared_ptr<ArrayBuffer>& data
) {
return nullptr;
}

std::shared_ptr<ArrayBuffer>
HybridCipher::final() {
return nullptr;
}

void
HybridCipher::copy() {}

bool
HybridCipher::setAAD(
const std::shared_ptr<ArrayBuffer>& data,
std::optional<double> plaintextLength
) {
return false;
}

bool
HybridCipher::setAutoPadding(
bool autoPad
) {
return false;
}

bool
HybridCipher::setAuthTag(
const std::shared_ptr<ArrayBuffer>& tag
) {
return false;
}

std::shared_ptr<ArrayBuffer>
HybridCipher::getAuthTag() {
return nullptr;
}

void
HybridCipher::setArgs(
const CipherArgs& args
) {
this->args = args;
init();
}

void
HybridCipher::init() {
// check if args are set
if (!args.has_value()) {
throw std::runtime_error("CipherArgs not set");
}
auto args = this->args.value();

// check if cipherType is valid
const EVP_CIPHER *const cipher = EVP_get_cipherbyname(args.cipherType.c_str());
if (cipher == nullptr) {
throw std::runtime_error("Invalid Cipher Algorithm: " + args.cipherType);
}
}

} // namespace margelo::nitro::crypto
63 changes: 63 additions & 0 deletions packages/react-native-quick-crypto/cpp/cipher/HybridCipher.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#include <memory>
#include <openssl/evp.h>
#include <optional>

#include "HybridCipherSpec.hpp"
#include "CipherArgs.hpp"

namespace margelo::nitro::crypto {

using namespace facebook;

class HybridCipher : public HybridCipherSpec {
public:
HybridCipher() : HybridObject(TAG) {}

public:
// Methods
std::shared_ptr<ArrayBuffer>
update(
const std::shared_ptr<ArrayBuffer>& data
) override;

std::shared_ptr<ArrayBuffer>
final() override;

void
copy() override;

void
setArgs(
const CipherArgs& args
) override;

bool
setAAD(
const std::shared_ptr<ArrayBuffer>& data,
std::optional<double> plaintextLength
) override;

bool
setAutoPadding(
bool autoPad
) override;

bool
setAuthTag(
const std::shared_ptr<ArrayBuffer>& tag
) override;

std::shared_ptr<ArrayBuffer>
getAuthTag() override;

private:
// Methods
void init();

private:
// Properties
std::optional<CipherArgs> args = std::nullopt;
};


} // namespace margelo::nitro::crypto
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#include "HybridEdKeyPair.hpp"

#include <memory>
#include <string>

#include "HybridEdKeyPair.hpp"

namespace margelo::nitro::crypto {

std::shared_ptr<Promise<void>>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include <memory>
#include <openssl/evp.h>
#include <openssl/err.h>
#include <memory>
#include <string>

#include "HybridEdKeyPairSpec.hpp"
Expand Down
1 change: 1 addition & 0 deletions packages/react-native-quick-crypto/nitro.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"androidCxxLibName": "QuickCrypto"
},
"autolinking": {
"Cipher": { "cpp": "HybridCipher" },
"EdKeyPair": { "cpp": "HybridEdKeyPair" },
"Pbkdf2": { "cpp": "HybridPbkdf2" },
"Random": { "cpp": "HybridRandom" }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# QuickCrypto+autolinking.cmake
# This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
# https://github.com/mrousavy/nitro
# Copyright © 2024 Marc Rousavy @ Margelo
# Copyright © 2025 Marc Rousavy @ Margelo
#

# This is a CMake file that adds all files generated by Nitrogen
Expand All @@ -27,6 +27,7 @@ target_sources(
# Autolinking Setup
../nitrogen/generated/android/QuickCryptoOnLoad.cpp
# Shared Nitrogen C++ sources
../nitrogen/generated/shared/c++/HybridCipherSpec.cpp
../nitrogen/generated/shared/c++/HybridEdKeyPairSpec.cpp
../nitrogen/generated/shared/c++/HybridKeyObjectHandleSpec.cpp
../nitrogen/generated/shared/c++/HybridPbkdf2Spec.cpp
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
/// QuickCrypto+autolinking.gradle
/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
/// https://github.com/mrousavy/nitro
/// Copyright © 2024 Marc Rousavy @ Margelo
/// Copyright © 2025 Marc Rousavy @ Margelo
///

/// This is a Gradle file that adds all files generated by Nitrogen
Expand Down
Loading
Loading