diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..b604c77 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,51 @@ +# Agent Guidelines for react-native-fast-crypto + +## Important: Edge Conventions + +Always query https://raw.githubusercontent.com/EdgeApp/edge-conventions/master/README.md if not already done in this session for additional project conventions and standards. + +## Project Documentation Index + +### Core Documentation + +- **README.md** - Project overview, quick start, build instructions + - When to read: First time working with the project, understanding basic usage + - Summary: Features, installation, API overview, native library building + +### Technical References + +- **docs/references/api-reference.md** - Complete API documentation + - When to read: Implementing crypto functions, understanding parameters/returns + - Summary: Detailed function signatures, parameters, examples for pbkdf2, scrypt, secp256k1 + +### Implementation Guides + +- **docs/guides/getting-started.md** - Integration and usage guide + - When to read: Setting up the library in a new project, common use cases + - Summary: Installation, basic usage, authentication, HD wallets, best practices + +- **docs/patterns/buffer-handling.md** - Binary data handling patterns + - When to read: Working with Uint8Array/Buffer conversions, encoding/decoding + - Summary: Buffer polyfill usage, Base64/Hex patterns, platform-specific handling + +## Build/Test/Lint Commands + +- **Test**: Run tests via the FastCryptoTest app: `cd FastCryptoTest && yarn ios` or `yarn android` +- **Format JS**: `yarn fix` (formats index.js with Prettier) +- **Format Android**: `yarn fix-android` (formats Java files) +- **Build native libs**: `yarn build-secp256k1` (builds secp256k1 native libraries) +- **Update test app**: `cd FastCryptoTest && yarn update` (updates test app dependencies) + +## Code Style Guidelines + +- **JavaScript**: No semicolons, single quotes, avoid arrow parens, no trailing commas (Prettier config) +- **Indentation**: 2 spaces (enforced by .editorconfig) +- **TypeScript**: Strict mode enabled, use CommonJS modules, target ES2016 +- **Type Definitions**: Maintained in index.d.ts, all functions use Uint8Array for binary data +- **Imports**: Use destructured imports from modules (e.g., `import { pbkdf2 } from 'react-native-fast-crypto'`) +- **Testing**: Use Chai for assertions with expect syntax +- **File encoding**: UTF-8 with LF line endings, trim trailing whitespace +- **Native code**: Follow platform conventions (Java for Android in android/, Objective-C for iOS in ios/) +- **Error handling**: Functions return Promises, handle errors with try/catch in async functions +- **Naming**: camelCase for functions/variables, PascalCase for classes/types +- **Buffer handling**: Use buffer npm package for Node.js Buffer compatibility, rfc4648 for base encoding diff --git a/README.md b/README.md index 679e586..4f8089d 100644 --- a/README.md +++ b/README.md @@ -2,33 +2,70 @@ This library implements fast, fully native crypto routines for React Native under iOS and Android. Fully built binaries are committed for both platforms but can also be built from scratch. +## Features + +- **PBKDF2** - Password-Based Key Derivation Function 2 with SHA-512 +- **scrypt** - Memory-hard key derivation function +- **secp256k1** - Elliptic curve operations for Bitcoin/Ethereum + - Public key creation + - Private key tweaking (for HD wallets) + - Public key tweaking + ## Getting started This library directly supports React Native v0.60+ with autolinking. Simply add react-native-fast-crypto to your application, and React Native will link the necessary native modules into your app. `npm install react-native-fast-crypto --save` -## Usage +For iOS, you'll also need to install pods: + +```bash +cd ios && pod install +``` + +## Quick Start ```javascript -import { scrypt } from 'react-native-fast-crypto'; +import { scrypt, pbkdf2, secp256k1 } from 'react-native-fast-crypto' -const data = Uint8Array.from([1, 250, 3, 4, 34, 64, 39, 43, 12]) +// Hash a password with scrypt +const password = Uint8Array.from([1, 250, 3, 4, 34, 64, 39, 43, 12]) const salt = Uint8Array.from([45, 124, 45, 29, 172, 238, 35]) +const hash = await scrypt(password, salt, 16384, 8, 1, 32) + +// Derive a key with PBKDF2 +const key = await pbkdf2.deriveAsync(password, salt, 2048, 64, 'sha512') -const result: Uint8Array = await crypto.scrypt(data, salt, 16384, 8, 1, 32) -console.log(result) +// Create a public key from a private key +const publicKey = await secp256k1.publicKeyCreate(privateKey, true) ``` +## API Documentation + +See the [detailed API reference](docs/references/api-reference.md) for complete documentation of all functions. + +### Core Functions + +- [`pbkdf2.deriveAsync`](docs/references/api-reference.md#pbkdf2deriveasync) - PBKDF2-SHA512 key derivation +- [`scrypt`](docs/references/api-reference.md#scrypt) - scrypt key derivation +- [`secp256k1.publicKeyCreate`](docs/references/api-reference.md#secp256k1publickeycreate) - Create public key from private key +- [`secp256k1.privateKeyTweakAdd`](docs/references/api-reference.md#secp256k1privatekeytweakadd) - Add tweak to private key +- [`secp256k1.publicKeyTweakAdd`](docs/references/api-reference.md#secp256k1publickeytweakadd) - Add tweak to public key + +## Guides + +- [Getting Started Guide](docs/guides/getting-started.md) - Installation and basic usage +- [Buffer Handling Patterns](docs/patterns/buffer-handling.md) - Working with binary data + ## Build libsecp256k1 from scratch (optional) The build process requires several pieces of software to be installed on the host system: -* autoconf -* automake -* git -* libtool +- autoconf +- automake +- git +- libtool To install these on the Mac, please use [Homebrew](http://brew.sh/): diff --git a/docs/guides/getting-started.md b/docs/guides/getting-started.md new file mode 100644 index 0000000..c569c9e --- /dev/null +++ b/docs/guides/getting-started.md @@ -0,0 +1,214 @@ +# Getting Started with react-native-fast-crypto + +This guide will help you integrate react-native-fast-crypto into your React Native application. + +## Installation + +### React Native 0.60+ + +For React Native 0.60 and above, the library supports autolinking: + +```bash +npm install react-native-fast-crypto --save +# or +yarn add react-native-fast-crypto +``` + +Then for iOS, install the native dependencies: + +```bash +cd ios && pod install +``` + +### Platform-Specific Setup + +#### iOS + +No additional setup required after pod install. + +#### Android + +No additional setup required with autolinking. + +## Basic Usage + +### 1. Import the library + +```javascript +import { pbkdf2, scrypt, secp256k1 } from 'react-native-fast-crypto' +``` + +### 2. Password Hashing with scrypt + +```javascript +import { scrypt } from 'react-native-fast-crypto' +import { utf8 } from './utf8' // You'll need a UTF-8 encoding utility + +async function hashPassword(password, salt) { + // Convert strings to Uint8Array + const passwordBytes = utf8.parse(password) + const saltBytes = utf8.parse(salt) + + // Derive key using scrypt + const derivedKey = await scrypt( + passwordBytes, + saltBytes, + 16384, // N: CPU/memory cost + 8, // r: block size + 1, // p: parallelization + 32 // key length in bytes + ) + + return derivedKey +} +``` + +### 3. Key Derivation with PBKDF2 + +```javascript +import { pbkdf2 } from 'react-native-fast-crypto' +import { base64 } from 'rfc4648' + +async function deriveKey(passphrase, salt) { + const key = await pbkdf2.deriveAsync( + passphrase, + salt, + 2048, // iterations + 64, // key length + 'sha512' // algorithm (only sha512 supported) + ) + + // Convert to base64 for storage + return base64.stringify(key) +} +``` + +### 4. Working with secp256k1 Keys + +```javascript +import { secp256k1 } from 'react-native-fast-crypto' +import { base16 } from 'rfc4648' + +async function generatePublicKey() { + // Generate or load your private key (32 bytes) + const privateKey = base16.parse('your-private-key-hex') + + // Create compressed public key + const publicKey = await secp256k1.publicKeyCreate(privateKey, true) + + console.log('Public key:', base16.stringify(publicKey)) +} +``` + +## Common Use Cases + +### 1. User Authentication + +```javascript +async function authenticateUser(username, password) { + // Create a salt from username (or store separately) + const salt = utf8.parse('salt:' + username) + const passwordBytes = utf8.parse(password) + + // Derive authentication key + const authKey = await scrypt(passwordBytes, salt, 16384, 8, 1, 32) + + // Use authKey for authentication + return base64.stringify(authKey) +} +``` + +### 2. HD Wallet Key Derivation + +```javascript +async function deriveChildKey(parentPrivateKey, chainCode, index) { + // Create tweak from chain code and index + // (This is a simplified example - real HD derivation is more complex) + const tweak = await createTweak(chainCode, index) + + // Derive child private key + const childPrivateKey = await secp256k1.privateKeyTweakAdd( + parentPrivateKey, + tweak + ) + + // Get corresponding public key + const childPublicKey = await secp256k1.publicKeyCreate( + childPrivateKey, + true // compressed + ) + + return { childPrivateKey, childPublicKey } +} +``` + +### 3. Secure Password Storage + +```javascript +async function hashPasswordForStorage(password) { + // Generate random salt + const salt = crypto.getRandomValues(new Uint8Array(32)) + + // Hash with high cost parameters + const hash = await scrypt( + utf8.parse(password), + salt, + 65536, // Higher N for more security + 8, + 1, + 64 // Longer hash + ) + + // Store both salt and hash + return { + salt: base64.stringify(salt), + hash: base64.stringify(hash) + } +} +``` + +## Best Practices + +1. **Always use salts**: Never hash passwords without a unique salt +2. **Choose appropriate parameters**: Higher iterations/memory costs increase security but also computation time +3. **Handle errors**: Always wrap async calls in try/catch blocks +4. **Secure key storage**: Never store private keys in plain text +5. **Use compressed keys**: When possible, use compressed public keys to save space + +## Testing Your Integration + +Create a simple test to verify the library is working: + +```javascript +import { scrypt } from 'react-native-fast-crypto' + +async function testCrypto() { + try { + const password = new Uint8Array([1, 2, 3, 4]) + const salt = new Uint8Array([5, 6, 7, 8]) + + const result = await scrypt(password, salt, 1024, 8, 1, 32) + console.log('Success! Key length:', result.length) + } catch (error) { + console.error('Crypto test failed:', error) + } +} +``` + +## Troubleshooting + +### iOS Build Issues + +- Ensure you've run `pod install` after installation +- Clean build folder: Xcode → Product → Clean Build Folder + +### Android Build Issues + +- Clean and rebuild: `cd android && ./gradlew clean` +- Ensure minSdkVersion is compatible + +### Runtime Errors + +- Check that all inputs are Uint8Array type +- Verify algorithm parameter is 'sha512' for pbkdf2 +- Ensure proper error handling for all async operations diff --git a/docs/patterns/buffer-handling.md b/docs/patterns/buffer-handling.md new file mode 100644 index 0000000..45362f0 --- /dev/null +++ b/docs/patterns/buffer-handling.md @@ -0,0 +1,184 @@ +# Buffer Handling Patterns + +This document describes patterns for working with buffers and binary data in react-native-fast-crypto. + +## Overview + +react-native-fast-crypto uses Uint8Array for all binary data operations. The library internally converts between different encodings as needed for native module communication. + +## Key Patterns + +### 1. Using the Buffer Polyfill + +The library uses the `buffer` npm package to provide Node.js Buffer compatibility: + +```javascript +const Buffer = require('buffer/').Buffer +``` + +This allows using `Buffer.allocUnsafe()` for performance when creating output buffers: + +```javascript +// From index.js - efficient buffer allocation +const outBuf = base16.parse(publicKeyHex, { out: Buffer.allocUnsafe }) +``` + +### 2. Base64 Bridge Pattern + +The native modules communicate using Base64 encoding to safely pass binary data: + +```javascript +// JavaScript side encodes to Base64 +const out = await RNFastCrypto.pbkdf2Sha512( + base64.stringify(data), + base64.stringify(salt), + iterations, + size +) +// Result is decoded from Base64 +return base64.parse(out, { out: Buffer.allocUnsafe }) +``` + +### 3. Hex String Pattern for secp256k1 + +The secp256k1 functions use hex strings for communication with native: + +```javascript +async function publicKeyCreate(privateKey: Uint8Array, compressed: boolean) { + // Convert to hex for native + const privateKeyHex = base16.stringify(privateKey) + + // Native returns hex + const publicKeyHex: string = await RNFastCrypto.secp256k1EcPubkeyCreate( + privateKeyHex, + compressed + ) + + // Convert back to Uint8Array + const outBuf = base16.parse(publicKeyHex, { out: Buffer.allocUnsafe }) + return outBuf +} +``` + +## Best Practices + +### 1. Consistent Encoding/Decoding + +Always use the same encoding library (rfc4648) throughout: + +```javascript +import { base16, base64 } from 'rfc4648' + +// Good - consistent library usage +const hex = base16.stringify(data) +const bytes = base16.parse(hex) + +// Avoid mixing different encoding libraries +``` + +### 2. Efficient Buffer Allocation + +Use `Buffer.allocUnsafe` when parsing to avoid zero-initialization overhead: + +```javascript +// Efficient - skips zero-initialization +const buffer = base64.parse(encoded, { out: Buffer.allocUnsafe }) + +// Less efficient - zeros memory first +const buffer = base64.parse(encoded) +``` + +### 3. Size Validation + +The scrypt function validates output size: + +```javascript +let uint8array = base64.parse(retval) +return uint8array.subarray(0, size) // Ensure exact size +``` + +### 4. Type Safety + +Always ensure inputs are Uint8Array: + +```javascript +// Good - explicit type +function processKey(key: Uint8Array) { + // ... +} + +// Validate at runtime if needed +if (!(data instanceof Uint8Array)) { + throw new Error('Input must be Uint8Array') +} +``` + +## Platform-Specific Handling + +### iOS + +- Uses UTF8String for hex conversions +- Pre-allocates buffers for output strings +- Handles null terminators in C strings + +### Android + +- Uses Base64.DEFAULT flag for standard encoding +- Converts through UTF-8 for PBKDF2 character encoding +- JNI layer handles hex string conversions + +## Common Patterns + +### 1. String to Binary Conversion + +```javascript +import { utf8 } from './utf8' + +// Convert UTF-8 string to bytes +const passwordBytes = utf8.parse('my password') + +// Use with crypto functions +const key = await scrypt(passwordBytes, salt, N, r, p, size) +``` + +### 2. Binary to Storage Format + +```javascript +// For storage/transmission +const keyHex = base16.stringify(privateKey) +const keyBase64 = base64.stringify(privateKey) + +// From storage +const privateKey = base16.parse(storedHex) +``` + +### 3. Working with Test Vectors + +```javascript +// Parse test vectors +const testKey = base16.parse( + '0d5a06c12ed605cdcd809b88f3299efda6bcb46f3c844d7003d7c9926adfa010' +) + +// Compare results +expect(base16.stringify(result).toLowerCase()).equals(expectedHex) +``` + +## Memory Considerations + +1. **Native buffers**: Freed automatically after use +2. **JavaScript buffers**: Garbage collected +3. **Large operations**: Consider chunking for very large inputs +4. **Sensitive data**: No built-in secure erasure - implement if needed + +## Error Handling + +Handle encoding errors gracefully: + +```javascript +try { + const decoded = base16.parse(userInput) +} catch (error) { + throw new Error('Invalid hex input: ' + error.message) +} +``` diff --git a/docs/references/api-reference.md b/docs/references/api-reference.md new file mode 100644 index 0000000..d0c14ad --- /dev/null +++ b/docs/references/api-reference.md @@ -0,0 +1,234 @@ +# react-native-fast-crypto API Reference + +This document provides a comprehensive API reference for the react-native-fast-crypto library. + +## Overview + +react-native-fast-crypto provides native implementations of cryptographic functions for React Native applications. All functions are asynchronous and return Promises. + +## Imports + +```javascript +import { pbkdf2, scrypt, secp256k1 } from 'react-native-fast-crypto' +``` + +## API Functions + +### pbkdf2.deriveAsync + +Derives a key using PBKDF2 (Password-Based Key Derivation Function 2) with SHA-512. + +```javascript +pbkdf2.deriveAsync( + data: Uint8Array, + salt: Uint8Array, + iterations: number, + keyLength: number, + algorithm: string +): Promise +``` + +**Parameters:** + +- `data`: The password/passphrase as a Uint8Array +- `salt`: The salt value as a Uint8Array +- `iterations`: Number of iterations (recommended: 2048 or higher) +- `keyLength`: Desired length of the derived key in bytes +- `algorithm`: Must be 'sha512' (only supported algorithm) + +**Returns:** Promise resolving to derived key as Uint8Array + +**Example:** + +```javascript +import { pbkdf2 } from 'react-native-fast-crypto' +import { utf8 } from './utf8' // Your UTF-8 encoding utility + +const password = utf8.parse('my secure password') +const salt = utf8.parse('salt value') +const key = await pbkdf2.deriveAsync(password, salt, 2048, 64, 'sha512') +``` + +### scrypt + +Derives a key using the scrypt key derivation function. + +```javascript +scrypt( + password: Uint8Array, + salt: Uint8Array, + N: number, + r: number, + p: number, + keyLength: number +): Promise +``` + +**Parameters:** + +- `password`: The password as a Uint8Array +- `salt`: The salt value as a Uint8Array +- `N`: CPU/memory cost parameter (must be power of 2, e.g., 16384) +- `r`: Block size parameter (typically 8) +- `p`: Parallelization parameter (typically 1) +- `keyLength`: Desired length of the derived key in bytes + +**Returns:** Promise resolving to derived key as Uint8Array + +**Example:** + +```javascript +import { scrypt } from 'react-native-fast-crypto' +import { utf8 } from './utf8' + +const password = utf8.parse('password123') +const salt = Uint8Array.from([45, 124, 45, 29, 172, 238, 35]) +const key = await scrypt(password, salt, 16384, 8, 1, 32) +``` + +### secp256k1.publicKeyCreate + +Creates a public key from a private key. + +```javascript +secp256k1.publicKeyCreate( + privateKey: Uint8Array, + compressed: boolean +): Promise +``` + +**Parameters:** + +- `privateKey`: The private key as a Uint8Array (32 bytes) +- `compressed`: Whether to return compressed (33 bytes) or uncompressed (65 bytes) public key + +**Returns:** Promise resolving to public key as Uint8Array + +**Example:** + +```javascript +import { secp256k1 } from 'react-native-fast-crypto' +import { base16 } from 'rfc4648' + +const privateKey = base16.parse( + '0d5a06c12ed605cdcd809b88f3299efda6bcb46f3c844d7003d7c9926adfa010' +) +const publicKey = await secp256k1.publicKeyCreate(privateKey, true) +// Result: compressed 33-byte public key +``` + +### secp256k1.privateKeyTweakAdd + +Adds a tweak value to a private key (used in HD wallet derivation). + +```javascript +secp256k1.privateKeyTweakAdd( + privateKey: Uint8Array, + tweak: Uint8Array +): Promise +``` + +**Parameters:** + +- `privateKey`: The private key as a Uint8Array (32 bytes) +- `tweak`: The tweak value as a Uint8Array (32 bytes) + +**Returns:** Promise resolving to tweaked private key as Uint8Array + +**Example:** + +```javascript +import { secp256k1 } from 'react-native-fast-crypto' +import { base16 } from 'rfc4648' + +const privateKey = base16.parse( + '0d5a06c12ed605cdcd809b88f3299efda6bcb46f3c844d7003d7c9926adfa010' +) +const tweak = base16.parse( + 'a0f24d30c336181342c875be8e1df4c29e25278282f7add9142c71c76c316c8a' +) +const tweakedKey = await secp256k1.privateKeyTweakAdd(privateKey, tweak) +``` + +### secp256k1.publicKeyTweakAdd + +Adds a tweak value to a public key (used in HD wallet derivation). + +```javascript +secp256k1.publicKeyTweakAdd( + publicKey: Uint8Array, + tweak: Uint8Array, + compressed: boolean +): Promise +``` + +**Parameters:** + +- `publicKey`: The public key as a Uint8Array (33 or 65 bytes) +- `tweak`: The tweak value as a Uint8Array (32 bytes) +- `compressed`: Whether to return compressed or uncompressed public key + +**Returns:** Promise resolving to tweaked public key as Uint8Array + +**Example:** + +```javascript +import { secp256k1 } from 'react-native-fast-crypto' +import { base16 } from 'rfc4648' + +const publicKey = base16.parse( + '0215a94b717775b487330c47db0324df661f66759af7435e54567f99371cda79e8' +) +const tweak = base16.parse( + 'ce547fb348b6d058c8c6190b781f98811cd77db75943fe681732ff8cafb4bb8d' +) +const tweakedPubKey = await secp256k1.publicKeyTweakAdd(publicKey, tweak, true) +``` + +## Data Encoding + +This library uses Uint8Array for all binary data. For encoding/decoding: + +- **Base16 (Hex)**: Use `rfc4648` library's `base16` module +- **Base64**: Use `rfc4648` library's `base64` module +- **UTF-8**: Implement your own or use a utility library + +Example using rfc4648: + +```javascript +import { base16, base64 } from 'rfc4648' + +// Hex to Uint8Array +const bytes = base16.parse('deadbeef') + +// Uint8Array to Hex +const hex = base16.stringify(bytes) + +// Base64 encoding +const b64 = base64.stringify(bytes) +``` + +## Error Handling + +All functions return Promises and should be used with async/await or .then()/.catch(): + +```javascript +try { + const key = await pbkdf2.deriveAsync(password, salt, 2048, 64, 'sha512') + // Use key... +} catch (error) { + console.error('Key derivation failed:', error) +} +``` + +Common errors: + +- `ErrorUnsupportedPbkdf2Algorithm`: When using algorithm other than 'sha512' +- Native module errors for invalid inputs or crypto operation failures + +## Performance Notes + +1. These functions use native implementations for optimal performance +2. scrypt operations log timing information to console +3. Large iteration counts or memory parameters will increase computation time +4. All operations are asynchronous to avoid blocking the UI thread diff --git a/index.d.ts b/index.d.ts new file mode 100644 index 0000000..99acb40 --- /dev/null +++ b/index.d.ts @@ -0,0 +1,122 @@ +declare module 'react-native-fast-crypto' { + /** + * Derives a key using the scrypt key derivation function. + * + * @param password - The password as a Uint8Array + * @param salt - The salt value as a Uint8Array + * @param N - CPU/memory cost parameter (must be power of 2, e.g., 16384) + * @param r - Block size parameter (typically 8) + * @param p - Parallelization parameter (typically 1) + * @param keyLength - Desired length of the derived key in bytes + * @returns Promise resolving to derived key as Uint8Array + * + * @example + * ```typescript + * const password = new TextEncoder().encode('password123'); + * const salt = crypto.getRandomValues(new Uint8Array(32)); + * const key = await scrypt(password, salt, 16384, 8, 1, 32); + * ``` + */ + export function scrypt( + password: Uint8Array, + salt: Uint8Array, + N: number, + r: number, + p: number, + keyLength: number + ): Promise + + /** + * PBKDF2 (Password-Based Key Derivation Function 2) namespace + */ + export namespace pbkdf2 { + /** + * Derives a key using PBKDF2 with SHA-512. + * + * @param data - The password/passphrase as a Uint8Array + * @param salt - The salt value as a Uint8Array + * @param iterations - Number of iterations (recommended: 2048 or higher) + * @param keyLength - Desired length of the derived key in bytes + * @param algorithm - Must be 'sha512' (only supported algorithm) + * @returns Promise resolving to derived key as Uint8Array + * @throws {Error} If algorithm is not 'sha512' + * + * @example + * ```typescript + * const password = new TextEncoder().encode('my secure password'); + * const salt = new TextEncoder().encode('salt value'); + * const key = await pbkdf2.deriveAsync(password, salt, 2048, 64, 'sha512'); + * ``` + */ + function deriveAsync( + data: Uint8Array, + salt: Uint8Array, + iterations: number, + keyLength: number, + algorithm: 'sha512' + ): Promise + } + + /** + * secp256k1 elliptic curve operations namespace + */ + export namespace secp256k1 { + /** + * Creates a public key from a private key. + * + * @param privateKey - The private key as a Uint8Array (must be 32 bytes) + * @param compressed - Whether to return compressed (33 bytes) or uncompressed (65 bytes) public key + * @returns Promise resolving to public key as Uint8Array + * + * @example + * ```typescript + * const privateKey = crypto.getRandomValues(new Uint8Array(32)); + * const publicKey = await secp256k1.publicKeyCreate(privateKey, true); + * ``` + */ + function publicKeyCreate( + privateKey: Uint8Array, + compressed: boolean + ): Promise + + /** + * Adds a tweak value to a private key (used in HD wallet derivation). + * + * @param privateKey - The private key as a Uint8Array (must be 32 bytes) + * @param tweak - The tweak value as a Uint8Array (must be 32 bytes) + * @returns Promise resolving to tweaked private key as Uint8Array + * + * @example + * ```typescript + * const privateKey = new Uint8Array(32); // Your private key + * const tweak = new Uint8Array(32); // Your tweak value + * const tweakedKey = await secp256k1.privateKeyTweakAdd(privateKey, tweak); + * ``` + */ + function privateKeyTweakAdd( + privateKey: Uint8Array, + tweak: Uint8Array + ): Promise + + /** + * Adds a tweak value to a public key (used in HD wallet derivation). + * + * @param publicKey - The public key as a Uint8Array (33 or 65 bytes) + * @param tweak - The tweak value as a Uint8Array (must be 32 bytes) + * @param compressed - Whether to return compressed or uncompressed public key + * @returns Promise resolving to tweaked public key as Uint8Array + * + * @example + * ```typescript + * const publicKey = new Uint8Array(33); // Your compressed public key + * const tweak = new Uint8Array(32); // Your tweak value + * const tweakedPubKey = await secp256k1.publicKeyTweakAdd(publicKey, tweak, true); + * ``` + */ + function publicKeyTweakAdd( + publicKey: Uint8Array, + tweak: Uint8Array, + compressed: boolean + ): Promise + } +} diff --git a/package.json b/package.json index af2d7fc..c88678f 100644 --- a/package.json +++ b/package.json @@ -20,12 +20,15 @@ "William Swanson " ], "main": "index.js", + "types": "index.d.ts", "files": [ "/android/build.gradle", "/android/jni/*", "/android/src/*", "/CHANGELOG.md", + "/docs/*", "/index.js", + "/index.d.ts", "/ios/*", "/package.json", "/react-native-fast-crypto.podspec",