@hinkal/crypto
v0.1.9
Published
The `@hinkal/crypto` package provides a suite of cryptographic utilities and tools essential for the Hinkal Protocol. It leverages modern cryptographic libraries to ensure secure and efficient operations within the protocol's ecosystem.
Downloads
700
Keywords
Readme
@hinkal/crypto
The @hinkal/crypto
package provides a suite of cryptographic utilities and tools essential for the Hinkal Protocol. It leverages modern cryptographic libraries to ensure secure and efficient operations within the protocol's ecosystem.
Table of Contents
Installation
Install the package using npm or yarn:
npm install @hinkal/crypto
or
yarn add @hinkal/crypto
Overview
The @hinkal/crypto
package offers various cryptographic operations and types used within the Hinkal Protocol. It is built using modern tooling and integrates seamlessly with other Hinkal packages.
Crypto Keys
The crypto-keys
module within the @hinkal/crypto
package is dedicated to managing the generation, handling, and utilization of cryptographic keys essential for various operations within the Hinkal Protocol. This module ensures secure creation, storage, and usage of keys required for encryption, decryption, and other cryptographic processes.
Key Components
UserKeys Class
The
UserKeys
class encapsulates user-specific cryptographic key operations. It provides methods to generate access tokens, wallet salts, backend tokens, and randomized stealth address pairs, ensuring secure handling of user keys.- Methods:
getAccessKey()
: Generates an access token by hashing the user's shielded private and public keys using the Poseidon hashing function.getWalletSalt(walletNonce: bigint)
: Generates a wallet salt by hashing the shielded public and private keys along with a provided nonce.getBackendToken()
: Generates a backend token used for access control on the backend by hashing the access key and the shielded public key.static getRandomizedStealthPair(s: bigint, privateKey: string)
: Generates a randomized stealth address pair (H0
,H1
) using the user's private key and a randomization factors
.
Example
import { UserKeys } from '@hinkal/crypto/crypto-keys'; import { poseidonHash } from '@hinkal/crypto'; // Initialize UserKeys with a private key const userKeys = new UserKeys('your-private-key-here'); // Generate an access key const accessKey = userKeys.getAccessKey(); console.log(`Access Key: ${accessKey}`); // Generate a wallet salt const walletSalt = userKeys.getWalletSalt(123456n); console.log(`Wallet Salt: ${walletSalt}`); // Generate a backend token const backendToken = userKeys.getBackendToken(); console.log(`Backend Token: ${backendToken}`); // Generate randomized stealth address pair const stealthPair = UserKeys.getRandomizedStealthPair(789n, 'your-private-key-here'); console.log(`Stealth Address H0: ${stealthPair.H0}`); console.log(`Stealth Address H1: ${stealthPair.H1}`);
- Methods:
EncryptionKeyPair Interface
Defines the structure for encryption key pairs used within the protocol.
export interface EncryptionKeyPair { privateKey: string; publicKey: string; } export const EncryptionKeyPairDefaultValue: EncryptionKeyPair = { privateKey: '', publicKey: '', };
Utility Functions
The
crypto-keys
module includes various utility functions to support key operations and cryptographic processes.Memoization (
memoizeFunc
)Utilizes memoization to enhance performance by caching the results of expensive function calls.
import { memoizeFunc } from '@hinkal/crypto/crypto-keys'; const memoizedFunction = memoizeFunc((input: bigint) => { // Expensive computation });
Key Utilities (
key-utils
)Provides helper functions for key operations such as encoding, decoding, and handling key-related transformations.
Integration with Zero-Knowledge Proofs
The
crypto-keys
module integrates seamlessly with zero-knowledge proof libraries likecircomlibjs
andsnarkjs
, facilitating the generation and verification of proofs necessary for the protocol's privacy-preserving features.
Usage
Importing Modules
You can import specific utilities or types from the crypto-keys
module as needed.
import { UserKeys } from '@hinkal/crypto/crypto-keys';
import { EncryptionKeyPair, EncryptionKeyPairDefaultValue } from '@hinkal/crypto/crypto-keys';
import { UserKeys } from '@hinkal/crypto/crypto-keys';
import { poseidonHash } from '@hinkal/crypto';
// Initialize UserKeys with a private key
const userKeys = new UserKeys('your-private-key-here');
// Generate an access key
const accessKey = userKeys.getAccessKey();
console.log(`Access Key: ${accessKey}`);
// Generate a wallet salt
const walletSalt = userKeys.getWalletSalt(123456n);
console.log(`Wallet Salt: ${walletSalt}`);
Zero-Knowledge Proofs
Integrates with circomlibjs
and snarkjs
to facilitate zero-knowledge proof generation and verification within the protocol.
Example Usage
Below are detailed examples demonstrating how to use various components within the @hinkal/crypto
package.
Using ZKProofWorker
The ZKProofWorker
allows you to perform zero-knowledge proof calculations in a web worker to keep the main thread responsive.
import { ZKProofWorker, ZKProofWorkerActionType } from '@hinkal/crypto';
// Initialize the worker
const zkProofWorker = new ZKProofWorker();
// Define the payload for calculating commitments
const commitmentPayload = {
type: ZKProofWorkerActionType.CALC_COMMITMENTS_SIBLING_AND_SIDES,
data: {
inputUtxosSerialized: [
// Array of serialized UTXOs
{
amount: 1000n,
erc20TokenAddress: '0xTokenAddress',
// ... other fields
},
// More UTXOs if needed
],
merkleTreeSerialized: {
// Serialized Merkle Tree data
root: '0xMerkleRoot',
// ... other fields
},
userSignature: '0xUserSignature',
},
};
// Listen for messages from the worker
zkProofWorker.onmessage = (event) => {
const result = event.data as ZKProofWorkerCalcCommitmentsReturn;
console.log('Commitment Siblings:', result.inCommitmentSiblings);
console.log('Commitment Sibling Sides:', result.inCommitmentSiblingSides);
};
// Handle errors
zkProofWorker.onerror = (error) => {
console.error('ZKProofWorker encountered an error:', error);
};
// Post the payload to the worker
zkProofWorker.postMessage(commitmentPayload);
Using IUtxoConstructor
The IUtxoConstructor
type defines the structure of a UTXO (Unspent Transaction Output) used within the protocol.
import { IUtxoConstructor } from '@hinkal/crypto';
/* Create a new UTXO */
const utxo: IUtxoConstructor = {
amount: 5000n,
erc20TokenAddress: '0xYourERC20TokenAddress',
timeStamp: new Date().toISOString(),
shieldedPrivateKey: '0xYourShieldedPrivateKey',
randomization: 123456789n,
stealthAddress: '0xYourStealthAddress',
encryptionKey: '0xYourEncryptionKey',
tokenId: 1,
isStake: false,
isStakeOrUnstakeInput: false,
isUnstakeOutput: false,
commitment: '0xYourCommitment',
nullifier: '0xYourNullifier',
};
Utilizing Private Wallet Functions with emporium.helpers.ts
The emporium.helpers.ts
provides utility functions for handling private wallet operations.
import { encodeEmporiumMetadata, emporiumOp } from '@hinkal/crypto';
/* Encode Emporium Metadata */
const ops = ['0xOperation1', '0xOperation2'];
const walletSalt = 'YourWalletSalt';
const metadata = encodeEmporiumMetadata(ops, walletSalt);
console.log('Encoded Metadata:', metadata);
/* Generate Emporium Operation Data */
const contractAddress = '0xContractAddress';
const functionName = 'functionName';
const functionArgs = ['arg1', 'arg2'];
const invokeWallet = true; // Whether to invoke the wallet
const valueInWei = 1000n; // Value in wei
const operationData = emporiumOp(contractAddress, functionName, functionArgs, invokeWallet, valueInWei);
console.log('Operation Data:', operationData);
Combining Workers and UTXOs in a Workflow
Here's an example of how to integrate ZKProofWorker
and IUtxoConstructor
in a typical workflow.
import { ZKProofWorker, ZKProofWorkerActionType, IUtxoConstructor } from '@hinkal/crypto';
// Initialize the ZKProofWorker
const zkProofWorker = new ZKProofWorker();
// Example UTXOs
const utxos: IUtxoConstructor[] = [
{
amount: 1000n,
erc20TokenAddress: '0xTokenAddress1',
timeStamp: new Date().toISOString(),
shieldedPrivateKey: '0xPrivateKey1',
// ... other fields
},
{
amount: 2000n,
erc20TokenAddress: '0xTokenAddress2',
timeStamp: new Date().toISOString(),
shieldedPrivateKey: '0xPrivateKey2',
// ... other fields
},
];
// Define Merkle Tree Data
const merkleTree = {
root: '0xMerkleRoot',
// ... other Merkle Tree fields
};
// Define the payload
const payload = {
type: ZKProofWorkerActionType.CALC_COMMITMENTS_SIBLING_AND_SIDES,
data: {
inputUtxosSerialized: utxos,
merkleTreeSerialized: merkleTree,
userSignature: '0xUserSignature',
},
};
// Listen for messages from the worker
zkProofWorker.onmessage = (event) => {
const result = event.data as ZKProofWorkerCalcCommitmentsReturn;
console.log('Commitment Siblings:', result.inCommitmentSiblings);
console.log('Commitment Sibling Sides:', result.inCommitmentSiblingSides);
};
// Handle errors
zkProofWorker.onerror = (error) => {
console.error('ZKProofWorker encountered an error:', error);
};
// Post the payload to the worker
zkProofWorker.postMessage(payload);