Skip to content
Open
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
51 changes: 51 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -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
55 changes: 46 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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/):

Expand Down
214 changes: 214 additions & 0 deletions docs/guides/getting-started.md
Original file line number Diff line number Diff line change
@@ -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
Loading
Loading