Module: ActionHash

Defined in:
lib/actionhash.rb

Overview

This is the main module for the ActionHash Gem

Defined Under Namespace

Classes: Error

Constant Summary collapse

MAX_ACTIONS_PER_KEY =
10

Class Method Summary collapse

Class Method Details

.create(prev_hash, input_data, key) ⇒ Object

Create a new Action Hash



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/actionhash.rb', line 19

def self.create(prev_hash, input_data, key)
  # Check if the key has reached its limit
  @key_usage_count[key] ||= 0
  if @key_usage_count[key] >= MAX_ACTIONS_PER_KEY
    raise Error, 'Key has reached its maximum usage. Please generate a new key.'
  end

  data = [prev_hash, input_data].join(',')
  encrypted_data = xor_encrypt(data, key)
  encrypted_hex = encrypted_data.unpack1('H*') # Convert to hex

  # Increment the usage count for the key
  @key_usage_count[key] += 1

  encrypted_hex
end

.down_layer(hash, key) ⇒ Object

Decrypt an Action Hash to its components



37
38
39
40
41
42
# File 'lib/actionhash.rb', line 37

def self.down_layer(hash, key)
  hex_decoded = [hash].pack('H*') # Convert from hex
  decrypted_data = xor_encrypt(hex_decoded, key)
  prev_hash, input_data = decrypted_data.split(',')
  { prev_hash: prev_hash.to_s, input_data: input_data.to_s }
end

.generate_new_keyObject

Generate a new key



14
15
16
# File 'lib/actionhash.rb', line 14

def self.generate_new_key
  SecureRandom.hex(8)
end

.valid_hash?(hash, key, level = 20) ⇒ Boolean

Validate if a hash can be traced back to ‘0’

Returns:



50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/actionhash.rb', line 50

def self.valid_hash?(hash, key, level = 20)
  current_level = 0
  loop do
    return false if current_level >= level

    decrypted_data = down_layer(hash, key)
    return true if decrypted_data[:prev_hash] == '0'
    return false if decrypted_data[:prev_hash].nil? || decrypted_data[:prev_hash].empty?

    hash = decrypted_data[:prev_hash]
    current_level += 1
  end
end

.xor_encrypt(data, key) ⇒ Object

XOR encrypt/decrypt (symmetric)



45
46
47
# File 'lib/actionhash.rb', line 45

def self.xor_encrypt(data, key)
  data.bytes.zip(key.bytes.cycle).map { |a, b| (a ^ b).chr }.join
end