Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/tkhq/sdk/llms.txt

Use this file to discover all available pages before exploring further.

@turnkey/crypto provides pure-JS cryptographic primitives used internally across Turnkey SDK packages. It covers P-256 (secp256r1) key generation, HPKE (Hybrid Public Key Encryption) encrypt/decrypt, signature format conversion, and bundle encryption/decryption for wallet import and export flows.
This is primarily an internal package. Most application developers do not need to import it directly. If you are building a wallet import/export UI, use the higher-level helpers in @turnkey/sdk-browser or @turnkey/iframe-stamper instead of calling these functions yourself.

Installation

npm install @turnkey/crypto
In React Native environments you must polyfill random byte generation by importing react-native-get-random-values before using this package.

Key generation

generateP256KeyPair

Generates a random P-256 key pair. Returns hex-encoded keys in compressed and uncompressed forms.
import { generateP256KeyPair } from "@turnkey/crypto";

const keyPair = generateP256KeyPair();
// keyPair.privateKey          — 64-char hex string
// keyPair.publicKey           — 66-char hex string (compressed, 02 or 03 prefix)
// keyPair.publicKeyUncompressed — 130-char hex string (04 prefix)
privateKey
string
32-byte private key as a hex string.
publicKey
string
33-byte compressed public key as a hex string.
publicKeyUncompressed
string
65-byte uncompressed public key as a hex string (prefixed with 04).

getPublicKey

Derives a P-256 public key from a private key.
import { getPublicKey } from "@turnkey/crypto";

const publicKey = getPublicKey(privateKeyBytes, true);  // compressed
const pubKeyUncompressed = getPublicKey(privateKeyBytes, false); // uncompressed
privateKey
Uint8Array | string
required
The private key as a Uint8Array or hex string.
isCompressed
boolean
Whether to return a compressed (33-byte) or uncompressed (65-byte) public key. Defaults to true.

compressRawPublicKey / uncompressRawPublicKey

Convert between compressed and uncompressed public key formats.
import { compressRawPublicKey, uncompressRawPublicKey } from "@turnkey/crypto";

// 65-byte uncompressed → 33-byte compressed
const compressed = compressRawPublicKey(uncompressedBytes);

// 33-byte compressed → 65-byte uncompressed
const uncompressed = uncompressRawPublicKey(compressedBytes);
// Second argument specifies curve: "CURVE_P256" (default) or "CURVE_SECP256K1"
const uncompressedK1 = uncompressRawPublicKey(compressedBytes, "CURVE_SECP256K1");

HPKE encryption

HPKE (RFC 9180) is used to encrypt key material for Turnkey’s wallet import and export flows.

hpkeEncrypt

Encrypts a plaintext buffer to an uncompressed P-256 target public key using an ephemeral sender key pair (standard HPKE mode).
import { hpkeEncrypt } from "@turnkey/crypto";

const encryptedBuf = hpkeEncrypt({
  plainTextBuf: new TextEncoder().encode("secret"),
  targetKeyBuf: receiverPublicKeyUncompressed, // Uint8Array, uncompressed
});
// Returns: Uint8Array — first 33 bytes are compressed sender public key,
//                       remaining bytes are the ciphertext

hpkeAuthEncrypt

Encrypts with an authenticated sender private key (authenticated HPKE mode).
import { hpkeAuthEncrypt } from "@turnkey/crypto";

const encryptedBuf = hpkeAuthEncrypt({
  plainTextBuf: new TextEncoder().encode("secret"),
  targetKeyBuf: receiverPublicKeyUncompressed,
  senderPriv: senderKeyPair.privateKey, // hex string
});

hpkeDecrypt

Decrypts a ciphertext encrypted with hpkeEncrypt or hpkeAuthEncrypt.
import { hpkeDecrypt } from "@turnkey/crypto";

const decryptedData = hpkeDecrypt({
  ciphertextBuf,  // Uint8Array
  encappedKeyBuf, // Uint8Array — uncompressed sender public key
  receiverPriv,   // hex string — receiver private key
});

formatHpkeBuf

Formats the output of hpkeEncrypt / hpkeAuthEncrypt into a JSON string with separated encappedPublic and ciphertext hex fields, as expected by Turnkey bundle APIs.
import { formatHpkeBuf } from "@turnkey/crypto";

const bundle = formatHpkeBuf(encryptedBuf);
// Returns: JSON string: { "encappedPublic": "<hex>", "ciphertext": "<hex>" }

End-to-end HPKE example

import {
  generateP256KeyPair,
  uncompressRawPublicKey,
  hpkeEncrypt,
  hpkeDecrypt,
} from "@turnkey/crypto";
import { uint8ArrayFromHexString } from "@turnkey/encoding";

const senderKeyPair = generateP256KeyPair();
const receiverKeyPair = generateP256KeyPair();

const receiverPublicKeyUncompressed = uncompressRawPublicKey(
  uint8ArrayFromHexString(receiverKeyPair.publicKey),
);

const plainText = "Hello, this is a secure message!";
const plainTextBuf = new TextEncoder().encode(plainText);

const encryptedData = hpkeEncrypt({
  plainTextBuf,
  targetKeyBuf: receiverPublicKeyUncompressed,
});

// Extract the encapsulated key buffer and the ciphertext
const encappedKeyBuf = encryptedData.slice(0, 33);
const ciphertextBuf = encryptedData.slice(33);

const decryptedData = hpkeDecrypt({
  ciphertextBuf,
  encappedKeyBuf: uncompressRawPublicKey(encappedKeyBuf),
  receiverPriv: receiverKeyPair.privateKey,
});

const decryptedText = new TextDecoder().decode(decryptedData);
// decryptedText === "Hello, this is a secure message!"

Bundle utilities

These higher-level functions handle the full bundle encrypt/decrypt flow including enclave signature verification.

encryptPrivateKeyToBundle

Encrypts a raw private key for import into Turnkey. Verifies the enclave signature before encrypting.
import { encryptPrivateKeyToBundle } from "@turnkey/crypto";

const bundle = await encryptPrivateKeyToBundle({
  privateKey: "<hex or base58 private key>",
  keyFormat: "HEXADECIMAL", // or "SOLANA"
  importBundle: "<JSON import bundle from Turnkey API>",
  userId: "<user-id>",
  organizationId: "<org-id>",
});

encryptWalletToBundle

Encrypts a BIP-39 mnemonic for wallet import.
import { encryptWalletToBundle } from "@turnkey/crypto";

const bundle = await encryptWalletToBundle({
  mnemonic: "word1 word2 ... word24",
  importBundle: "<JSON import bundle from Turnkey API>",
  userId: "<user-id>",
  organizationId: "<org-id>",
});

decryptExportBundle

Decrypts an encrypted export bundle returned by the Turnkey API. Verifies the enclave signature.
import { decryptExportBundle } from "@turnkey/crypto";

const mnemonic = await decryptExportBundle({
  exportBundle: "<JSON export bundle from Turnkey API>",
  embeddedKey: "<receiver private key hex>",
  organizationId: "<org-id>",
  returnMnemonic: true,  // false returns raw hex private key
  keyFormat: "HEXADECIMAL", // or "SOLANA"
});

decryptCredentialBundle

Decrypts an email auth or OAuth credential bundle.
import { decryptCredentialBundle } from "@turnkey/crypto";

const credential = decryptCredentialBundle(
  credentialBundle, // bs58check-encoded bundle
  embeddedKey,      // receiver private key hex
);
// Returns decrypted data as a hex string

Signature utilities

verifyStampSignature

Verifies an ECDSA P-256 signature from a Turnkey stamp.
import { verifyStampSignature } from "@turnkey/crypto";

const isValid = await verifyStampSignature(
  publicKey,  // hex string
  signature,  // DER-encoded ECDSA signature hex string
  signedData, // the original data that was signed
);

toDerSignature / fromDerSignature

Convert between raw (r‖s) and ASN.1 DER-encoded ECDSA signature formats.
import { toDerSignature, fromDerSignature } from "@turnkey/crypto";

// Raw hex r||s → DER hex
const derHex = toDerSignature(rawSignatureHex);

// DER hex → raw Uint8Array (r||s)
const rawBytes = fromDerSignature(derSignatureHex);

verifySessionJwtSignature

Verifies a session JWT signature against Turnkey’s production notarizer key.
import { verifySessionJwtSignature } from "@turnkey/crypto";

const isValid = await verifySessionJwtSignature(jwt);

Attestation verification

For advanced use cases, @turnkey/crypto also exports functions for verifying Turnkey enclave attestation proofs:
import {
  verify,                  // Verify app proof + boot proof pair
  verifyAppProofSignature, // Verify only the app proof signature
  verifyCertificateChain,  // Verify AWS Nitro certificate chain
  verifyCoseSign1Sig,      // Verify COSE_Sign1 attestation signature
} from "@turnkey/crypto";
See Turnkey’s whitepaper for details on the attestation model.