class Eth::Key::Encrypter
def self.perform(key, password, options = {})
def self.perform(key, password, options = {}) new(key, options).perform(password) end
def address
def address Eth::Key.new(priv: key).address end
def cipher
def cipher @cipher ||= OpenSSL::Cipher.new(cipher_name).tap do |cipher| cipher.encrypt cipher.iv = iv cipher.key = derived_key[0, (key_length / 2)] end end
def cipher_name
def cipher_name "aes-128-ctr" end
def data
def data { crypto: { cipher: cipher_name, cipherparams: { iv: bin_to_hex(iv), }, ciphertext: bin_to_hex(encrypted_key), kdf: "pbkdf2", kdfparams: { c: iterations, dklen: 32, prf: prf, salt: bin_to_hex(salt), }, mac: bin_to_hex(mac), }, id: id, version: 3, }.tap do |data| data[:address] = address unless options[:skip_address] end end
def derive_key(password)
def derive_key(password) @derived_key = OpenSSL::PKCS5.pbkdf2_hmac(password, salt, iterations, key_length, digest) end
def digest
def digest @digest ||= OpenSSL::Digest.new digest_name end
def digest_name
def digest_name "sha256" end
def encrypt
def encrypt @encrypted_key = cipher.update(hex_to_bin key) + cipher.final end
def id
def id @id ||= options[:id] || SecureRandom.uuid end
def initialize(key, options = {})
def initialize(key, options = {}) @key = key @options = options end
def iterations
def iterations options[:iterations] || 262_144 end
def iv
def iv @iv ||= if options[:iv] hex_to_bin options[:iv] else SecureRandom.random_bytes(iv_length) end end
def iv_length
def iv_length 16 end
def key_length
def key_length 32 end
def mac
def mac keccak256(derived_key[(key_length / 2), key_length] + encrypted_key) end
def perform(password)
def perform(password) derive_key password encrypt data.to_json end
def prf
def prf "hmac-#{digest_name}" end
def salt
def salt @salt ||= if options[:salt] hex_to_bin options[:salt] else SecureRandom.random_bytes(salt_length) end end
def salt_length
def salt_length 32 end