import * as crypto from 'crypto' ; import * as assert from 'assert' ; const HASH_ALGORITHM = 'sha256' ; const ENCRYPTION_ALGORITHM = 'aes-256-gcm' ; const IV_LENGTH = 12 ; const AUTH_TAG_LENGTH = 16 ; const SHARED_SECRET_GENERATION_STRING = Buffer . from ( 'ilp_stream_shared_secret' , 'utf8' ) ; export const randomBytes = crypto . randomBytes ; export async function hash ( preimage ) { const h = crypto . createHash ( HASH_ALGORITHM ) ; h . update ( preimage ) ; return Promise . resolve ( h . digest ( ) ) ; } export async function encrypt ( pskEncryptionKey , ... buffers ) { return Promise . resolve ( encryptSync ( pskEncryptionKey , ... buffers ) ) ; } function encryptSync ( pskEncryptionKey , ... buffers ) { const iv = crypto . randomBytes ( IV_LENGTH ) ; const cipher = crypto . createCipheriv ( ENCRYPTION_ALGORITHM , pskEncryptionKey , iv ) ; const ciphertext = [ ] ; for ( let buffer of buffers ) { ciphertext . push ( cipher . update ( buffer ) ) ; } ciphertext . push ( cipher . final ( ) ) ; const tag = cipher . getAuthTag ( ) ; ciphertext . unshift ( iv , tag ) ; return Buffer . concat ( ciphertext ) ; } export async function decrypt ( pskEncryptionKey , data ) { return Promise . resolve ( decryptSync ( pskEncryptionKey , data ) ) ; } function decryptSync ( pskEncryptionKey , data ) { assert ( data . length > 0 , 'cannot decrypt empty buffer' ) ; const nonce = data . slice ( 0 , IV_LENGTH ) ; const tag = data . slice ( IV_LENGTH , IV_LENGTH + AUTH_TAG_LENGTH ) ; const encrypted = data . slice ( IV_LENGTH + AUTH_TAG_LENGTH ) ; const decipher = crypto . createDecipheriv ( ENCRYPTION_ALGORITHM , pskEncryptionKey , nonce ) ; decipher . setAuthTag ( tag ) ; return Buffer . concat ( [ decipher . update ( encrypted ) , decipher . final ( ) ] ) ; } export async function hmac ( key , message ) { return Promise . resolve ( hmacSync ( key , message ) ) ; } function hmacSync ( key , message ) { const h = crypto . createHmac ( HASH_ALGORITHM , key ) ; h . update ( message ) ; return h . digest ( ) ; } export function generateSharedSecretFromToken ( seed , token ) { const keygen = hmacSync ( seed , SHARED_SECRET_GENERATION_STRING ) ; const sharedSecret = hmacSync ( keygen , token ) ; return sharedSecret ; } export function generateReceiptHMAC ( secret , message ) { return hmacSync ( secret , message ) ; } export function encryptConnectionAddressToken ( seed , token ) { return encryptSync ( seed , token ) ; } export function decryptConnectionAddressToken ( seed , token ) { return decryptSync ( seed , token ) ; }