LogoLogo
  • Welcome
  • XRPL Basics
    • Getting Started
    • Payments
    • Reading and subscribing to Transactions
    • Writing and reading memos
    • Non Fungible Tokens
    • PathFinding
    • Escrow
    • Price Oracles
    • Tickets
    • Multi-Signature
  • Token Issuance and Liquidity
    • Creating Accounts
    • Issuing Tokens
    • Creating an AMM Pool
  • Cyphered Chat on XRPL
    • Set up
    • Set up Keys
    • Cypher the message
    • Set up the memo & send the tx
    • Get the message and decypher it
  • EVM Sidechain
    • Connecting Metamask
    • Bridging Assets
    • Remix
    • Banking App
    • Banking Contract Key Concepts
  • Tools
    • Xaman Setup
    • Metamask Setup
Powered by GitBook
On this page
Export as PDF
  1. Cyphered Chat on XRPL

Cypher the message

Now that we have their public key, we can encrypt our secret message. Remember our "outside-in" principle: we use THEIR public (outside) key to encrypt the message, which ensures that only THEIR private (inside) key can decrypt it. The message gets transformed into a scrambled format that is completely unreadable to anyone who might intercept it - only the owner of the matching private key can convert it back to the original text. Each encrypted message is unique, even if you encrypt the same text multiple times, adding an extra layer of security.

import tweetnacl from 'tweetnacl';
import { Buffer } from "buffer";
import { Wallet } from "xrpl";
import {
  edwardsToMontgomeryPub,
  edwardsToMontgomeryPriv,
} from "@noble/curves/ed25519";

const { box, randomBytes } = tweetnacl;

/**
 * Encrypts a message using X25519 (Montgomery curve) for Diffie-Hellman key exchange
 *
 * @param message - Plain text message to encrypt
 * @param recipientPublicKey - Recipient's Ed25519 public key (hex encoded)
 * @param senderSecretKey - Sender's Ed25519 private key (hex encoded)
 * @returns JSON string containing base64 encoded encrypted message and nonce
 *
 * Steps:
 * 1. Convert hex keys to byte arrays
 * 2. Generate random nonce for uniqueness
 * 3. Convert message to bytes
 * 4. Convert Ed25519 keys to X25519 (Montgomery) format for encryption
 * 5. Encrypt using NaCl box with converted keys
 * 6. Return encrypted message and nonce as base64 JSON
 */
export function encryptMessage(
  message: string,
  recipientPublicKey: string,
  senderSecretKey: string,
): string {
  const pubKeyBytes = Buffer.from(recipientPublicKey.slice(2), "hex");
  const secretKeyBytes = Buffer.from(senderSecretKey.slice(2), "hex");

  const nonce = randomBytes(box.nonceLength);
  const messageUint8 = Buffer.from(message);

  const pubKeyCurve = edwardsToMontgomeryPub(pubKeyBytes);
  const privKeyCurve = edwardsToMontgomeryPriv(secretKeyBytes);

  const encryptedMessage = box(messageUint8, nonce, pubKeyCurve, privKeyCurve);

  return JSON.stringify({
    encrypted: Buffer.from(encryptedMessage).toString("base64"),
    nonce: Buffer.from(nonce).toString("base64"),
  });
}

function main() {
  const recipientPublicKey ="Recipient pubkey goes here";
  const myWallet = Wallet.fromSeed("your seed goes here");

  const cypheredMessage = encryptMessage(
    "Hello World",
    recipientPublicKey,
    myWallet.privateKey,
  );
  console.log(cypheredMessage);
}

main();
PreviousSet up KeysNextSet up the memo & send the tx

Last updated 4 months ago