Skip to content
Merged
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
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,5 @@ tsconfig.tsbuildinfo
.java-version

# development stuffs
example0/
*scratch*

Binary file modified bun.lockb
Binary file not shown.
8 changes: 4 additions & 4 deletions example/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ PODS:
- ReactCommon/turbomodule/core
- Yoga
- OpenSSL-Universal (3.3.2000)
- QuickCrypto (1.0.0-beta.5):
- QuickCrypto (1.0.0-beta.7):
- DoubleConversion
- glog
- hermes-engine
Expand Down Expand Up @@ -1720,7 +1720,7 @@ DEPENDENCIES:
- glog (from `../../node_modules/react-native/third-party-podspecs/glog.podspec`)
- hermes-engine (from `../../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec`)
- NitroModules (from `../../node_modules/react-native-nitro-modules`)
- QuickCrypto (from `../node_modules/react-native-quick-crypto`)
- QuickCrypto (from `../../node_modules/react-native-quick-crypto`)
- RCT-Folly (from `../../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec`)
- RCT-Folly/Fabric (from `../../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec`)
- RCTDeprecation (from `../../node_modules/react-native/ReactApple/Libraries/RCTFoundation/RCTDeprecation`)
Expand Down Expand Up @@ -1807,7 +1807,7 @@ EXTERNAL SOURCES:
NitroModules:
:path: "../../node_modules/react-native-nitro-modules"
QuickCrypto:
:path: "../node_modules/react-native-quick-crypto"
:path: "../../node_modules/react-native-quick-crypto"
RCT-Folly:
:podspec: "../../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec"
RCTDeprecation:
Expand Down Expand Up @@ -1940,7 +1940,7 @@ SPEC CHECKSUMS:
hermes-engine: 46f1ffbf0297f4298862068dd4c274d4ac17a1fd
NitroModules: 47399393665e69228b29a17f501c7b453679ccc0
OpenSSL-Universal: b60a3702c9fea8b3145549d421fdb018e53ab7b4
QuickCrypto: 8d76ae3a0bf60509f671193eb4ed666a80da34cb
QuickCrypto: 2a4bcacfec3cc81d56205e6b12f190d492f9a1e7
RCT-Folly: 84578c8756030547307e4572ab1947de1685c599
RCTDeprecation: fde92935b3caa6cb65cbff9fbb7d3a9867ffb259
RCTRequired: 75c6cee42d21c1530a6f204ba32ff57335d19007
Expand Down
2 changes: 1 addition & 1 deletion example/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
"devDependencies": {
"@babel/core": "7.25.2",
"@babel/plugin-transform-class-static-block": "7.26.0",
"@babel/preset-env": "7.25.3",
"@babel/preset-env": "7.26.0",
"@babel/runtime": "7.25.0",
"@eslint/compat": "^1.1.1",
"@eslint/js": "^9.9.0",
Expand Down
53 changes: 38 additions & 15 deletions example/src/tests/ed25519/ed25519_tests.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/* eslint-disable @typescript-eslint/no-unused-expressions */
import { Ed, randomBytes, ab2str } from 'react-native-quick-crypto';
import { Buffer } from '@craftzdog/react-native-buffer';
// import type {
// // KeyObject,
// // CFRGKeyPairType,
Expand All @@ -12,6 +13,10 @@ import { test } from '../util';

const SUITE = 'ed25519';

const encoder = new TextEncoder();
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const encode = (data: any): Uint8Array => encoder.encode(JSON.stringify(data));

/*
const jwkOptions: GenerateKeyPairOptions = {
publicKeyEncoding: {
Expand Down Expand Up @@ -75,25 +80,30 @@ test(SUITE, 'sign/verify - bad signature does not verify', async () => {
expect(verified).to.be.false;
});

test(
SUITE,
'sign/verify with non-internally generated private key',
async () => {
let ed1: Ed | null = new Ed('ed25519', {});
await ed1.generateKeyPair();
const priv = ed1.getPrivateKey();
ed1 = null;
test(SUITE, 'sign/verify - switched args does not verify', async () => {
const ed = new Ed('ed25519', {});
await ed.generateKeyPair();
const signature = await ed.sign(data1.buffer);
// verify(message, signature) is switched
const verified = await ed.verify(data1.buffer, signature);
expect(verified).to.be.false;
});

const ed2 = new Ed('ed25519', {});
const signature = await ed2.sign(data1.buffer, priv);
const verified = await ed2.verify(signature, data1.buffer, priv);
expect(verified).to.be.true;
},
);
test(SUITE, 'sign/verify - non-internally generated private key', async () => {
let ed1: Ed | null = new Ed('ed25519', {});
await ed1.generateKeyPair();
const priv = ed1.getPrivateKey();
ed1 = null;

const ed2 = new Ed('ed25519', {});
const signature = await ed2.sign(data1.buffer, priv);
const verified = await ed2.verify(signature, data1.buffer, priv);
expect(verified).to.be.true;
});

test(
SUITE,
'sign/verify with bad non-internally generated private key',
'sign/verify - bad non-internally generated private key',
async () => {
let ed1: Ed | null = new Ed('ed25519', {});
await ed1.generateKeyPair();
Expand All @@ -108,3 +118,16 @@ test(
expect(verified).to.be.false;
},
);

test(SUITE, 'sign/verify - Uint8Arrays', () => {
const data = { b: 'world', a: 'hello' };

const ed1 = new Ed('ed25519', {});
ed1.generateKeyPairSync();
const priv = new Uint8Array(ed1.getPrivateKey());

const ed2 = new Ed('ed25519', {});
const signature = new Uint8Array(ed2.signSync(encode(data), priv));
const verified = ed2.verifySync(signature, encode(data), priv);
expect(verified).to.be.true;
});
5 changes: 4 additions & 1 deletion example/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
"**.*.tsx",
],
"compilerOptions": {
"jsx": "react"
"jsx": "react",
"paths": {
"react-native-quick-crypto": ["../packages/react-native-quick-crypto/src"],
},
},
}
11 changes: 7 additions & 4 deletions packages/react-native-quick-crypto/QuickCrypto.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ require "json"

package = JSON.parse(File.read(File.join(__dir__, "package.json")))

Pod::UI.puts "[QuickCrypto] crypto just got quicker 💨"
Pod::UI.puts "[QuickCrypto] 💨 crypto just got quicker"

Pod::Spec.new do |s|
s.name = "QuickCrypto"
Expand All @@ -12,7 +12,11 @@ Pod::Spec.new do |s|
s.license = package["license"]
s.authors = package["authors"]

s.platforms = { :ios => min_ios_version_supported }
s.ios.deployment_target = min_ios_version_supported
s.visionos.deployment_target = 1.0
s.macos.deployment_target = 10.13
s.tvos.deployment_target = 13.4

s.source = { :git => "https://github.com/margelo/react-native-quick-crypto.git", :tag => "#{s.version}" }

s.source_files = [
Expand All @@ -32,7 +36,6 @@ Pod::Spec.new do |s|
load 'nitrogen/generated/ios/QuickCrypto+autolinking.rb'
add_nitrogen_files(s)

install_modules_dependencies(s)
s.dependency "OpenSSL-Universal"

install_modules_dependencies(s)
end
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@ namespace margelo::nitro::crypto {
virtual std::shared_ptr<ArrayBuffer> getPrivateKey() = 0;
virtual std::shared_ptr<Promise<std::shared_ptr<ArrayBuffer>>> sign(const std::shared_ptr<ArrayBuffer>& message, const std::optional<std::shared_ptr<ArrayBuffer>>& key) = 0;
virtual std::shared_ptr<ArrayBuffer> signSync(const std::shared_ptr<ArrayBuffer>& message, const std::optional<std::shared_ptr<ArrayBuffer>>& key) = 0;
virtual std::shared_ptr<Promise<bool>> verify(const std::shared_ptr<ArrayBuffer>& message, const std::shared_ptr<ArrayBuffer>& signature, const std::optional<std::shared_ptr<ArrayBuffer>>& key) = 0;
virtual bool verifySync(const std::shared_ptr<ArrayBuffer>& message, const std::shared_ptr<ArrayBuffer>& signature, const std::optional<std::shared_ptr<ArrayBuffer>>& key) = 0;
virtual std::shared_ptr<Promise<bool>> verify(const std::shared_ptr<ArrayBuffer>& signature, const std::shared_ptr<ArrayBuffer>& message, const std::optional<std::shared_ptr<ArrayBuffer>>& key) = 0;
virtual bool verifySync(const std::shared_ptr<ArrayBuffer>& signature, const std::shared_ptr<ArrayBuffer>& message, const std::optional<std::shared_ptr<ArrayBuffer>>& key) = 0;
virtual void setCurve(const std::string& curve) = 0;

protected:
Expand Down
2 changes: 1 addition & 1 deletion packages/react-native-quick-crypto/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@
"jest": "29.7.0",
"nitro-codegen": "0.18.2",
"prettier": "3.3.3",
"react-native-builder-bob": "0.33.3",
"react-native-builder-bob": "0.35.2",
"release-it": "17.6.0",
"typescript": "5.1.6",
"typescript-eslint": "^8.1.0"
Expand Down
35 changes: 19 additions & 16 deletions packages/react-native-quick-crypto/src/ed.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { NitroModules } from 'react-native-nitro-modules';
import { binaryLikeToArrayBuffer as toAB } from './utils';
import type { EdKeyPair } from './specs/edKeyPair.nitro';
import type { CFRGKeyPairType, KeyPairGenConfig } from './utils';
import type { BinaryLike, CFRGKeyPairType, KeyPairGenConfig } from './utils';

export class Ed {
type: CFRGKeyPairType;
Expand Down Expand Up @@ -44,33 +45,35 @@ export class Ed {
return this.native.getPrivateKey();
}

async sign(message: ArrayBuffer, key?: ArrayBuffer): Promise<ArrayBuffer> {
return key ? this.native.sign(message, key) : this.native.sign(message);
async sign(message: BinaryLike, key?: BinaryLike): Promise<ArrayBuffer> {
return key
? this.native.sign(toAB(message), toAB(key))
: this.native.sign(toAB(message));
}

signSync(message: ArrayBuffer, key?: ArrayBuffer): ArrayBuffer {
signSync(message: BinaryLike, key?: BinaryLike): ArrayBuffer {
return key
? this.native.signSync(message, key)
: this.native.signSync(message);
? this.native.signSync(toAB(message), toAB(key))
: this.native.signSync(toAB(message));
}

async verify(
message: ArrayBuffer,
signature: ArrayBuffer,
key?: ArrayBuffer,
signature: BinaryLike,
message: BinaryLike,
key?: BinaryLike,
): Promise<boolean> {
return key
? this.native.verify(message, signature, key)
: this.native.verify(message, signature);
? this.native.verify(toAB(signature), toAB(message), toAB(key))
: this.native.verify(toAB(signature), toAB(message));
}

verifySync(
message: ArrayBuffer,
signature: ArrayBuffer,
key?: ArrayBuffer,
signature: BinaryLike,
message: BinaryLike,
key?: BinaryLike,
): boolean {
return key
? this.native.verifySync(message, signature, key)
: this.native.verifySync(message, signature);
? this.native.verifySync(toAB(signature), toAB(message), toAB(key))
: this.native.verifySync(toAB(signature), toAB(message));
}
}
18 changes: 7 additions & 11 deletions packages/react-native-quick-crypto/src/random.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Buffer } from '@craftzdog/react-native-buffer';
import type { ArrayBufferView, RandomCallback } from './utils';
import type { ABV, RandomCallback } from './utils';
import { abvToArrayBuffer } from './utils';
import { NitroModules } from 'react-native-nitro-modules';
import type { Random } from './specs/random.nitro';
Expand All @@ -14,25 +14,25 @@ function getNative(): Random {
return random;
}

export function randomFill<T extends ArrayBufferView>(
export function randomFill<T extends ABV>(
buffer: T,
callback: RandomCallback<T>,
): void;

export function randomFill<T extends ArrayBufferView>(
export function randomFill<T extends ABV>(
buffer: T,
offset: number,
callback: RandomCallback<T>,
): void;

export function randomFill<T extends ArrayBufferView>(
export function randomFill<T extends ABV>(
buffer: T,
offset: number,
size: number,
callback: RandomCallback<T>,
): void;

export function randomFill(buffer: ArrayBufferView, ...rest: unknown[]): void {
export function randomFill(buffer: ABV, ...rest: unknown[]): void {
if (typeof rest[rest.length - 1] !== 'function') {
throw new Error('No callback provided to randomFill');
}
Expand Down Expand Up @@ -65,17 +65,13 @@ export function randomFill(buffer: ArrayBufferView, ...rest: unknown[]): void {
);
}

export function randomFillSync<T extends ArrayBufferView>(
export function randomFillSync<T extends ABV>(
buffer: T,
offset?: number,
size?: number,
): T;

export function randomFillSync(
buffer: ArrayBufferView,
offset: number = 0,
size?: number,
) {
export function randomFillSync(buffer: ABV, offset: number = 0, size?: number) {
getNative();
buffer = abvToArrayBuffer(buffer);
const res = random.randomFillSync(buffer, offset, size ?? buffer.byteLength);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,13 @@ export interface EdKeyPair
signSync(message: ArrayBuffer, key?: ArrayBuffer): ArrayBuffer;

verify(
message: ArrayBuffer,
signature: ArrayBuffer,
message: ArrayBuffer,
key?: ArrayBuffer,
): Promise<boolean>;
verifySync(
message: ArrayBuffer,
signature: ArrayBuffer,
message: ArrayBuffer,
key?: ArrayBuffer,
): boolean;

Expand Down
Loading
Loading