# 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.

```typescript
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();
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.xrpl-commons.org/cyphered-chat-on-xrpl/cypher-the-message.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
