Class: Reth::Keystore

Inherits:
Object
  • Object
show all
Defined in:
lib/reth/keystore.rb

Defined Under Namespace

Classes: AES128CTR, PBKDF2

Constant Summary collapse

KDF =
{
  'pbkdf2' => PBKDF2
}.freeze
CIPHER =
{
  'aes-128-ctr' => AES128CTR
}.freeze

Class Method Summary collapse

Class Method Details

.decode_json(jsondata, pw) ⇒ Object

Raises:

  • (ArgumentError)


98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/reth/keystore.rb', line 98

def decode_json(jsondata, pw)
  jsondata = Hashie::Mash.new jsondata

  cryptdata = jsondata.crypto || jsondata.Crypto
  raise ArgumentError, "JSON data must contain 'crypto' object" unless cryptdata

  kdfparams = cryptdata.kdfparams
  kdf = KDF[cryptdata.kdf].new kdfparams

  cipherparams = cryptdata.cipherparams
  cipher = CIPHER[cryptdata.cipher].new cipherparams

  derivedkey = kdf.eval pw
  raise ValueError, "Derived key must be at least 32 bytes long" unless derivedkey.size >= 32

  enckey = derivedkey[0,16]
  ct = Utils.decode_hex cryptdata.ciphertext
  o = cipher.decrypt ct, enckey

  mac1 = Utils.keccak256 "#{derivedkey[16,16]}#{ct}"
  mac2 = Utils.decode_hex cryptdata.mac
  raise ValueError, "MAC mismatch. Password incorrect?" unless mac1 == mac2

  o
end

.make_json(priv, pw, kdf = PBKDF2.new, cipher = AES128CTR.new) ⇒ Object



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/reth/keystore.rb', line 74

def make_json(priv, pw, kdf=PBKDF2.new, cipher=AES128CTR.new)
  derivedkey = kdf.eval pw

  enckey = derivedkey[0,16]
  c = cipher.encrypt priv, enckey

  mac = Utils.keccak256 "#{derivedkey[16,16]}#{c}"
  uuid = SecureRandom.uuid

  {
    crypto: {
      cipher: cipher.name,
      ciphertext: Utils.encode_hex(c),
      cipherparams: cipher.params,
      kdf: kdf.name,
      kdfparams: kdf.params,
      mac: Utils.encode_hex(mac),
      version: 1
    },
    id: uuid,
    version: 3
  }
end

.validate(json) ⇒ Bool

Check if json has the structure of a keystore file version 3.

Note that this test is not complete, e.g. it doesn’t check key derivation or cipher parameters.

Parameters:

  • json (Hash)

    data load from json file

Returns:

  • (Bool)

    'true` if the data appears to be valid, otherwise `false`



134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/reth/keystore.rb', line 134

def validate(json)
  return false unless json.has_key?('crypto') || json.has_key?('Crypto')
  return false unless json['version'] == 3

  crypto = json['crypto'] || json['Crypto']
  return false unless crypto.has_key?('cipher')
  return false unless crypto.has_key?('ciphertext')
  return false unless crypto.has_key?('kdf')
  return false unless crypto.has_key?('mac')

  true
end