Created
March 25, 2025 23:59
-
-
Save sondreb/d7ac64573554f3773fb586a21109775c to your computer and use it in GitHub Desktop.
Data Encryption
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { bytesToHex, hexToBytes, bytesToUtf8, utf8ToBytes } from '@noble/ciphers/utils'; | |
import { randomBytes } from '@noble/ciphers/webcrypto'; | |
import { secp256k1 } from '@noble/curves/secp256k1'; | |
import { xchacha20poly1305 } from '@noble/ciphers/chacha'; | |
// Encrypting data | |
function encryptWithPublicKey(publicKey, plaintext) { | |
// Generate a random ephemeral private key | |
const ephemeralPrivateKey = secp256k1.utils.randomPrivateKey(); | |
// Derive the ephemeral public key | |
const ephemeralPublicKey = secp256k1.getPublicKey(ephemeralPrivateKey); | |
// Compute shared secret using ECDH | |
const sharedSecret = secp256k1.getSharedSecret(ephemeralPrivateKey, publicKey); | |
// Use a key derivation step to create a 256-bit key for XChaCha20 | |
const encryptionKey = sharedSecret.slice(0, 32); // First 32 bytes of the shared secret | |
// Create a random 192-bit nonce (24 bytes) | |
const nonce = randomBytes(24); | |
// Encrypt the plaintext with XChaCha20-Poly1305 | |
const cipher = xchacha20poly1305(encryptionKey, nonce); | |
const ciphertext = cipher.encrypt(new TextEncoder().encode(plaintext)); | |
return { | |
ephemeralPublicKey, // Include ephemeral public key for decryption | |
nonce, // Include nonce for decryption | |
ciphertext, | |
}; | |
} | |
// Decrypting data | |
function decryptWithPrivateKey(privateKey, encryptedData) { | |
const { ephemeralPublicKey, nonce, ciphertext } = encryptedData; | |
// Compute shared secret using ECDH | |
const sharedSecret = secp256k1.getSharedSecret(privateKey, ephemeralPublicKey); | |
// Use a key derivation step to create a 256-bit key for XChaCha20 | |
const encryptionKey = sharedSecret.slice(0, 32); // First 32 bytes of the shared secret | |
// Decrypt the ciphertext with XChaCha20-Poly1305 | |
const cipher = xchacha20poly1305(encryptionKey, nonce); | |
const plaintext = cipher.decrypt(ciphertext); | |
return new TextDecoder().decode(plaintext); | |
} | |
const receiverPrivateKey = secp256k1.utils.randomPrivateKey(); | |
const receiverPublicKey = secp256k1.getPublicKey(receiverPrivateKey); | |
const receiverPrivateKeyHex = bytesToHex(receiverPrivateKey); | |
const receiverPublicKeyHex = bytesToHex(receiverPublicKey); | |
console.log('Private Key:', receiverPrivateKeyHex); | |
console.log('Public Key:', receiverPublicKeyHex); | |
const plaintext = 'Hello, XChaCha20-Poly1305!'; | |
console.log('Plaintext:', plaintext); | |
const encryptedData = encryptWithPublicKey(receiverPublicKey, plaintext); | |
const encryptedDataHex = { | |
ephemeralPublicKey: bytesToHex(encryptedData.ephemeralPublicKey), | |
nonce: bytesToHex(encryptedData.nonce), | |
ciphertext: bytesToHex(encryptedData.ciphertext), | |
}; | |
console.log('Encrypted Data:', encryptedDataHex); | |
const decryptedData = decryptWithPrivateKey(receiverPrivateKey, encryptedData); | |
console.log('Decrypted Data:', decryptedData); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment