Skip to content

Commit

Permalink
Merge pull request #67 from serenity-kit/add-crypto_box_seed_keypair
Browse files Browse the repository at this point in the history
feat: add crypto_box_seed_keypair and crypto_box_SEEDBYTES
  • Loading branch information
nikgraf authored Jun 11, 2024
2 parents a770f31 + 5f1e5e9 commit f3ff304
Show file tree
Hide file tree
Showing 7 changed files with 114 additions and 3 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,11 @@ import {
crypto_aead_xchacha20poly1305_ietf_keygen,
crypto_box_easy,
crypto_box_keypair,
crypto_box_seed_keypair,
crypto_box_open_easy,
crypto_box_PUBLICKEYBYTES,
crypto_box_SECRETKEYBYTES,
crypto_box_SEEDBYTES,
crypto_box_seal,
crypto_box_seal_open,
crypto_kdf_CONTEXTBYTES,
Expand Down
33 changes: 33 additions & 0 deletions cpp/react-native-libsodium.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ namespace ReactNativeLibsodium
jsiRuntime.global().setProperty(jsiRuntime, "jsi_crypto_box_PUBLICKEYBYTES", static_cast<int>(crypto_box_PUBLICKEYBYTES));
jsiRuntime.global().setProperty(jsiRuntime, "jsi_crypto_box_SECRETKEYBYTES", static_cast<int>(crypto_box_SECRETKEYBYTES));
jsiRuntime.global().setProperty(jsiRuntime, "jsi_crypto_box_NONCEBYTES", static_cast<int>(crypto_box_NONCEBYTES));
jsiRuntime.global().setProperty(jsiRuntime, "jsi_crypto_box_SEEDBYTES", static_cast<int>(crypto_box_SEEDBYTES));
jsiRuntime.global().setProperty(jsiRuntime, "jsi_crypto_aead_xchacha20poly1305_ietf_KEYBYTES", static_cast<int>(crypto_aead_xchacha20poly1305_ietf_KEYBYTES));
jsiRuntime.global().setProperty(jsiRuntime, "jsi_crypto_aead_xchacha20poly1305_ietf_NPUBBYTES", static_cast<int>(crypto_aead_xchacha20poly1305_ietf_NPUBBYTES));
jsiRuntime.global().setProperty(jsiRuntime, "jsi_crypto_kdf_KEYBYTES", static_cast<int>(crypto_kdf_KEYBYTES));
Expand Down Expand Up @@ -469,6 +470,38 @@ namespace ReactNativeLibsodium

jsiRuntime.global().setProperty(jsiRuntime, "jsi_crypto_box_keypair", std::move(jsi_crypto_box_keypair));

auto jsi_crypto_box_seed_keypair = jsi::Function::createFromHostFunction(
jsiRuntime,
jsi::PropNameID::forUtf8(jsiRuntime, "crypto_box_seed_keypair"),
1,
[](jsi::Runtime &runtime, const jsi::Value &thisValue, const jsi::Value *arguments, size_t count) -> jsi::Value
{
const std::string functionName = "crypto_box_seed_keypair";

std::string seedArgumentName = "seed";
unsigned int seedArgumentPosition = 0;
validateIsArrayBuffer(functionName, runtime, arguments[seedArgumentPosition], seedArgumentName, true);

auto seedDataArrayBuffer =
arguments[seedArgumentPosition].asObject(runtime).getArrayBuffer(runtime);

unsigned long long publickeyLength = crypto_box_PUBLICKEYBYTES;
unsigned long long secretkeyLength = crypto_box_SECRETKEYBYTES;
std::vector<uint8_t> publickey(publickeyLength);
std::vector<uint8_t> secretkey(secretkeyLength);
crypto_box_seed_keypair(publickey.data(), secretkey.data(), seedDataArrayBuffer.data(runtime));

jsi::Object returnPublicKeyBufferAsObject = arrayBufferAsObject(runtime, publickey);
jsi::Object returnSecretKeyBufferAsObject = arrayBufferAsObject(runtime, secretkey);

auto object = jsi::Object(runtime);
object.setProperty(runtime, "publicKey", returnPublicKeyBufferAsObject);
object.setProperty(runtime, "secretKey", returnSecretKeyBufferAsObject);
return object;
});

jsiRuntime.global().setProperty(jsiRuntime, "jsi_crypto_box_seed_keypair", std::move(jsi_crypto_box_seed_keypair));

auto jsi_crypto_sign_keypair = jsi::Function::createFromHostFunction(
jsiRuntime,
jsi::PropNameID::forUtf8(jsiRuntime, "crypto_sign_keypair"),
Expand Down
3 changes: 2 additions & 1 deletion example/src/components/TestResults.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@ import '../tests/crypto_auth_keygen_test';
import '../tests/crypto_auth_test';
import '../tests/crypto_auth_verify_test';
import '../tests/crypto_box_easy_test';
import '../tests/crypto_box_seal_test';
import '../tests/crypto_box_keypair_test';
import '../tests/crypto_box_open_easy_test';
import '../tests/crypto_box_seal_test';
import '../tests/crypto_box_seed_keypair_test';
import '../tests/crypto_generichash_test';
import '../tests/crypto_kdf_derive_from_key_test';
import '../tests/crypto_kdf_keygen_test';
Expand Down
2 changes: 2 additions & 0 deletions example/src/tests/constants_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
crypto_auth_KEYBYTES,
crypto_box_PUBLICKEYBYTES,
crypto_box_SECRETKEYBYTES,
crypto_box_SEEDBYTES,
crypto_kdf_CONTEXTBYTES,
crypto_kdf_KEYBYTES,
crypto_secretbox_KEYBYTES,
Expand All @@ -22,6 +23,7 @@ test('constants', () => {
expect(crypto_secretbox_NONCEBYTES).toEqual(24);
expect(crypto_box_PUBLICKEYBYTES).toEqual(32);
expect(crypto_box_SECRETKEYBYTES).toEqual(32);
expect(crypto_box_SEEDBYTES).toEqual(32);
expect(crypto_aead_xchacha20poly1305_ietf_KEYBYTES).toEqual(32);
expect(crypto_kdf_KEYBYTES).toEqual(32);
expect(crypto_kdf_CONTEXTBYTES).toEqual(8);
Expand Down
45 changes: 45 additions & 0 deletions example/src/tests/crypto_box_seed_keypair_test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import {
crypto_box_PUBLICKEYBYTES,
crypto_box_SECRETKEYBYTES,
crypto_box_seed_keypair,
from_base64,
} from 'react-native-libsodium';
import { expect, test } from '../utils/testRunner';

test('crypto_box_seed_keypair', () => {
const seed = from_base64('KI70zL1z1j7-IRjn1YG-qgkbbR0QCFggiqWcAA5bXIk');

const keyPair = crypto_box_seed_keypair(seed);
const keyPairBase64 = crypto_box_seed_keypair(seed, 'base64');

expect(keyPair.keyType).toEqual('x25519');
expect(keyPair.publicKey.length).toEqual(crypto_box_PUBLICKEYBYTES);
expect(typeof keyPair.publicKey).toEqual('object');
expect(keyPair.publicKey).toEqual(
new Uint8Array([
108, 139, 52, 190, 205, 39, 174, 21, 111, 62, 10, 12, 133, 182, 39, 113,
221, 51, 135, 183, 139, 101, 52, 64, 119, 21, 133, 7, 85, 73, 93, 7,
])
);

expect(keyPair.privateKey.length).toEqual(crypto_box_SECRETKEYBYTES);
expect(typeof keyPair.privateKey).toEqual('object');
expect(keyPair.privateKey).toEqual(
new Uint8Array([
28, 193, 69, 156, 167, 29, 242, 149, 39, 5, 162, 42, 15, 246, 31, 73, 182,
214, 112, 23, 214, 0, 1, 101, 65, 125, 229, 229, 10, 180, 106, 124,
])
);

expect(keyPairBase64.keyType).toEqual('x25519');
expect(keyPairBase64.publicKey.length).toEqual(43);
expect(typeof keyPairBase64.publicKey).toEqual('string');
expect(keyPairBase64.publicKey).toEqual(
'bIs0vs0nrhVvPgoMhbYncd0zh7eLZTRAdxWFB1VJXQc'
);
expect(keyPairBase64.privateKey.length).toEqual(43);
expect(typeof keyPairBase64.privateKey).toEqual('string');
expect(keyPairBase64.privateKey).toEqual(
'HMFFnKcd8pUnBaIqD_YfSbbWcBfWAAFlQX3l5Qq0anw'
);
});
27 changes: 27 additions & 0 deletions src/lib.native.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ declare global {
var jsi_crypto_box_PUBLICKEYBYTES: number;
var jsi_crypto_box_SECRETKEYBYTES: number;
var jsi_crypto_box_NONCEBYTES: number;
var jsi_crypto_box_SEEDBYTES: number;
var jsi_crypto_aead_xchacha20poly1305_ietf_KEYBYTES: number;
var jsi_crypto_aead_xchacha20poly1305_ietf_NPUBBYTES: number;
var jsi_crypto_kdf_KEYBYTES: number;
Expand Down Expand Up @@ -79,6 +80,10 @@ declare global {
publicKey: ArrayBuffer;
secretKey: ArrayBuffer;
};
function jsi_crypto_box_seed_keypair(seed: ArrayBuffer): {
publicKey: ArrayBuffer;
secretKey: ArrayBuffer;
};
function jsi_crypto_sign_keypair(): {
publicKey: ArrayBuffer;
secretKey: ArrayBuffer;
Expand Down Expand Up @@ -183,6 +188,7 @@ export const crypto_secretbox_NONCEBYTES =
export const crypto_box_PUBLICKEYBYTES = global.jsi_crypto_box_PUBLICKEYBYTES;
export const crypto_box_SECRETKEYBYTES = global.jsi_crypto_box_SECRETKEYBYTES;
export const crypto_box_NONCEBYTES = global.jsi_crypto_box_NONCEBYTES;
export const crypto_box_SEEDBYTES = global.jsi_crypto_box_SEEDBYTES;
export const crypto_aead_xchacha20poly1305_ietf_KEYBYTES =
global.jsi_crypto_aead_xchacha20poly1305_ietf_KEYBYTES;
export const crypto_aead_xchacha20poly1305_ietf_NPUBBYTES =
Expand Down Expand Up @@ -345,6 +351,26 @@ export function crypto_box_keypair(outputFormat: OutputFormat): unknown {
};
}

export function crypto_box_seed_keypair(
seed: Uint8Array,
outputFormat?: Uint8ArrayOutputFormat | null
): KeyPair;
export function crypto_box_seed_keypair(
seed: Uint8Array,
outputFormat: StringOutputFormat
): StringKeyPair;
export function crypto_box_seed_keypair(
seed: Uint8Array,
outputFormat: OutputFormat
): unknown {
const result = global.jsi_crypto_box_seed_keypair(seed.buffer);
return {
keyType: 'x25519',
publicKey: convertToOutputFormat(result.publicKey, outputFormat),
privateKey: convertToOutputFormat(result.secretKey, outputFormat),
};
}

export function crypto_sign_keypair(
outputFormat?: Uint8ArrayOutputFormat | null
): KeyPair;
Expand Down Expand Up @@ -813,6 +839,7 @@ export default {
crypto_aead_xchacha20poly1305_ietf_keygen,
crypto_aead_xchacha20poly1305_ietf_NPUBBYTES,
crypto_box_easy,
crypto_box_seed_keypair,
crypto_box_keypair,
crypto_box_NONCEBYTES,
crypto_box_open_easy,
Expand Down
5 changes: 3 additions & 2 deletions src/lib.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ export type {
StringSecretBox,
Uint8ArrayOutputFormat,
} from 'libsodium-wrappers';
import * as hkdf from '@noble/hashes/hkdf';
import { sha256 } from '@noble/hashes/sha256';
import type {
CryptoBox,
CryptoKX,
Expand All @@ -30,8 +32,6 @@ import type {
StringSecretBox,
Uint8ArrayOutputFormat,
} from 'libsodium-wrappers';
import * as hkdf from '@noble/hashes/hkdf';
import { sha256 } from '@noble/hashes/sha256';

let isLoadSumoVersion = false;

Expand Down Expand Up @@ -153,6 +153,7 @@ export const ready = new Promise<void>(async (resolve) => {
crypto_box_easy = lib.crypto_box_easy;
crypto_box_easy_afternm = lib.crypto_box_easy_afternm;
crypto_box_keypair = lib.crypto_box_keypair;
crypto_box_seed_keypair = lib.crypto_box_seed_keypair;
crypto_box_open_detached = lib.crypto_box_open_detached;
crypto_box_open_easy = lib.crypto_box_open_easy;
crypto_box_open_easy_afternm = lib.crypto_box_open_easy_afternm;
Expand Down

0 comments on commit f3ff304

Please sign in to comment.