const EthCrypto = require('eth-crypto'); const crypto = require('crypto'); const fs = require('fs'); const { idData, prA, puB, prB } = require('./parameters'); // File paths const originalFile = './paper.pdf'; const encryptedFile = './C.pdf'; const decryptedFile = './decrypted.pdf'; const keyFile = './k.txt'; const ivFile = './iv.txt'; const HMACFILE = './HMAC.txt'; const hFile = './h.txt'; const idFile = './id.txt'; const fcFile = './fc.txt'; // Function to encrypt the notification message const encryptM = async () => { try { // Read the original file into a buffer const fileBuffer = fs.readFileSync(originalFile); // Encrypt the file buffer using ECIES const ECIES_output_params = await EthCrypto.encryptWithPublicKey( puB, fileBuffer.toString('hex') ); console.log("ECIES output params: ", ECIES_output_params); // Compress the ephemeral public key from the encryption output const ephemPublicKeyCompressed = EthCrypto.publicKey.compress( ECIES_output_params.ephemPublicKey ); // Convert the compressed ephemeral public key to a hex string with '0x' prefix const k = `0x${ephemPublicKeyCompressed}`; // Convert the initialization vector (IV) from hex to base64 const bufferIV = Buffer.from(ECIES_output_params.iv, 'hex'); const iv = bufferIV.toString('base64'); // Convert the HMAC (Hash-based Message Authentication Code) from hex to base64 const bufferHMAC = Buffer.from(ECIES_output_params.mac, 'hex'); const HMAC = bufferHMAC.toString('base64'); // Save the encryption output params to their respective files fs.writeFileSync(encryptedFile, ECIES_output_params.ciphertext, 'hex'); fs.writeFileSync(keyFile, k); fs.writeFileSync(ivFile, iv); fs.writeFileSync(HMACFILE, HMAC); } catch (error) { console.error('Error reading or writing file:', error); } } // Function to compute h const getH = async () => { try { // Read the encrypted file into a buffer const fileBuffer = fs.readFileSync(encryptedFile); // Create a SHA-256 hash object const hashSum = crypto.createHash('sha256'); hashSum.update(fileBuffer); // Compute the hash as a hexadecimal string const hex = hashSum.digest('hex'); // Format the hash as a Solidity-compatible bytes32 string const solidityBytes32 = `0x${hex}`; console.log('SHA-256 file hash (Bytes32):', solidityBytes32); // Write the hash to the specified file fs.writeFileSync(hFile, solidityBytes32); } catch (error) { console.error('Error reading or hashing file:', error); } } // Function to obtain the notification ID const getID = async () => { try { // Read the h file into a buffer const fileBuffer = fs.readFileSync(hFile); const h = fileBuffer.toString(); // Calculate the Keccak-256 hash of the given inputs to get the notification ID const signHash = EthCrypto.hash.keccak256([ { type: 'address', value: idData.addrA }, { type: 'address', value: idData.addrB }, { type: 'address', value: idData.addrSC }, { type: 'uint256', value: idData.tm }, { type: 'uint256', value: idData.td }, { type: 'bytes32', value: h } ]); // Write the calculated hash to the file specified by idFile fs.writeFileSync(idFile, signHash); console.log("id = ", signHash); } catch (error) { console.error('Error writing file:', error); } } // Function to obtain f(C) const getFC = async () => { try { // Read the contents of the files idFile, hFile and convert them to a string const idBuffer = fs.readFileSync(idFile); const id = idBuffer.toString(); const hBuffer = fs.readFileSync(hFile); const h = hBuffer.toString(); // Create a keccak256 hash of the concatenated values const signHash = EthCrypto.hash.keccak256([ { type: 'bytes32', value: id }, { type: 'uint256', value: idData.tm }, { type: 'uint256', value: idData.td }, { type: 'bytes32', value: h } ]); // Sign the keccak256 hash with the private key prA const fc = EthCrypto.sign( prA, signHash ); // Write the signed hash (fc) to the fcFile fs.writeFileSync(fcFile, fc); console.log("Fc: ", fc); } catch (error) { console.error('Error writing file:', error); } } // Function to verify the signer of f(C) const verifyFC = async () => { try { // Read the contents of the files idFile, hFile, fcFile and convert them to a string const idBuffer = fs.readFileSync(idFile); const id = idBuffer.toString(); const hBuffer = fs.readFileSync(hFile); const h = hBuffer.toString(); const fc = fs.readFileSync(fcFile, 'utf8'); // Compute the keccak256 hash of the given data fields const signHash = EthCrypto.hash.keccak256([ { type: 'bytes32', value: id }, { type: 'uint256', value: idData.tm }, { type: 'uint256', value: idData.td }, { type: 'bytes32', value: h } ]); // Recover the signer's address from the given signature (fc) and the hash (signHash) const signer = EthCrypto.recover( fc, signHash ); // Log success message and the signer's address (@A) console.log('FC verified successfully!'); console.log('Signer: ', signer); } catch (error) { console.error('Error reading file:', error); } } // Function to decrypt C and recover the original file const decryptC = async () => { try { // Read encrypted data from file const encryptedBuffer = fs.readFileSync(encryptedFile, 'hex'); // Read HMAC and encryption key from files const hmacBase64 = fs.readFileSync(HMACFILE, 'utf8'); const key = fs.readFileSync(keyFile, 'utf8'); // Decompress the public key for encryption const ephemPublicKey = EthCrypto.publicKey.decompress( key.substring(2) // Removing '0x' prefix before decompression ); // Format the decompressed public key with its prefix '04' const k = `04${ephemPublicKey}`; // Read Initialization Vector (IV) from file and convert from Base64 to string const ivBase64 = fs.readFileSync(ivFile, 'utf8'); const ivBuffer = Buffer.from(ivBase64, 'base64'); const iv = ivBuffer.toString('hex'); // Convert HMAC from Base64 to hexadecimal string const hmacBuffer = Buffer.from(hmacBase64, 'base64'); const hmac = hmacBuffer.toString('hex'); // Prepare parameters required for ECIES decryption const ECIES_output_params = { iv: iv, ephemPublicKey: k, ciphertext: encryptedBuffer, mac: hmac }; // Decrypt the encrypted data using a private key (prB) const decrypted = await EthCrypto.decryptWithPrivateKey( prB, ECIES_output_params ); // Convert decrypted data from hexadecimal string to Buffer and write to a file const decryptedBuffer = Buffer.from(decrypted, 'hex'); fs.writeFileSync(decryptedFile, decryptedBuffer); } catch (error) { console.error('Error reading or writing file:', error); } } // Execute all functions in order const execute = async () => { await encryptM(); await getH(); await getID(); await getFC(); await verifyFC(); await decryptC(); } execute();