Class: BlockIo::Helper
- Inherits:
-
Object
- Object
- BlockIo::Helper
- Defined in:
- lib/block_io/helper.rb
Class Method Summary collapse
- .base58_to_int(base58_val) ⇒ Object
- .decode_base58(base58_val) ⇒ Object
-
.decrypt(encrypted_data, b64_enc_key, iv = nil, cipher_type = "AES-256-ECB") ⇒ Object
Decrypts a block of data (encrypted_data) given an encryption key.
- .encode_base58(hex) ⇒ Object
-
.encrypt(data, b64_enc_key, iv = nil, cipher_type = "AES-256-ECB") ⇒ Object
Encrypts a block of data given an encryption key.
- .extractKey(encrypted_data, b64_enc_key, use_low_r = true) ⇒ Object
-
.int_to_base58(int_val, leading_zero_bytes = 0) ⇒ Object
courtesy bitcoin-ruby.
- .low_r?(r) ⇒ Boolean
- .pinToAesKey(secret_pin, iterations = 2048) ⇒ Object
- .sha256(value) ⇒ Object
- .signData(inputs, keys) ⇒ Object
Class Method Details
.base58_to_int(base58_val) ⇒ Object
139 140 141 142 143 144 145 146 147 |
# File 'lib/block_io/helper.rb', line 139 def self.base58_to_int(base58_val) alpha = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz" int_val, base = 0, alpha.size base58_val.reverse.each_char.with_index do |char,index| raise ArgumentError, "Value not a valid Base58 String." unless char_index = alpha.index(char) int_val += char_index*(base**index) end int_val end |
.decode_base58(base58_val) ⇒ Object
154 155 156 157 158 159 160 161 |
# File 'lib/block_io/helper.rb', line 154 def self.decode_base58(base58_val) s = Helper.base58_to_int(base58_val).to_s(16) s = (s.bytesize.odd? ? ("0" << s) : s) s = "" if s == "00" leading_zero_bytes = (base58_val.match(/^([1]+)/) ? $1 : "").size s = ("00"*leading_zero_bytes) << s if leading_zero_bytes > 0 s end |
.decrypt(encrypted_data, b64_enc_key, iv = nil, cipher_type = "AES-256-ECB") ⇒ Object
Decrypts a block of data (encrypted_data) given an encryption key
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
# File 'lib/block_io/helper.rb', line 100 def self.decrypt(encrypted_data, b64_enc_key, iv = nil, cipher_type = "AES-256-ECB") response = nil begin aes = OpenSSL::Cipher.new(cipher_type) aes.decrypt aes.key = b64_enc_key.unpack("m0")[0] aes.iv = iv unless iv.nil? response = aes.update(encrypted_data.unpack("m0")[0]) << aes.final rescue Exception => e # decryption failed, must be an invalid Secret PIN raise Exception.new("Invalid Secret PIN provided.") end response end |
.encode_base58(hex) ⇒ Object
149 150 151 152 |
# File 'lib/block_io/helper.rb', line 149 def self.encode_base58(hex) leading_zero_bytes = (hex.match(/^([0]+)/) ? $1 : "").size / 2 ("1"*leading_zero_bytes) << Helper.int_to_base58( hex.to_i(16) ) end |
.encrypt(data, b64_enc_key, iv = nil, cipher_type = "AES-256-ECB") ⇒ Object
Encrypts a block of data given an encryption key
119 120 121 122 123 124 125 |
# File 'lib/block_io/helper.rb', line 119 def self.encrypt(data, b64_enc_key, iv = nil, cipher_type = "AES-256-ECB") aes = OpenSSL::Cipher.new(cipher_type) aes.encrypt aes.key = b64_enc_key.unpack("m0")[0] aes.iv = iv unless iv.nil? [aes.update(data) << aes.final].pack("m0") end |
.extractKey(encrypted_data, b64_enc_key, use_low_r = true) ⇒ Object
52 53 54 55 56 57 58 59 60 61 |
# File 'lib/block_io/helper.rb', line 52 def self.extractKey(encrypted_data, b64_enc_key, use_low_r = true) # passphrase is in plain text # encrypted_data is in base64, as it was stored on Block.io # returns the private key extracted from the given encrypted data decrypted = self.decrypt(encrypted_data, b64_enc_key) Key.from_passphrase(decrypted, use_low_r) end |
.int_to_base58(int_val, leading_zero_bytes = 0) ⇒ Object
courtesy bitcoin-ruby
129 130 131 132 133 134 135 136 137 |
# File 'lib/block_io/helper.rb', line 129 def self.int_to_base58(int_val, leading_zero_bytes=0) alpha = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz" base58_val, base = "", alpha.size while int_val > 0 int_val, remainder = int_val.divmod(base) base58_val = alpha[remainder] << base58_val end base58_val end |
.low_r?(r) ⇒ Boolean
93 94 95 96 97 |
# File 'lib/block_io/helper.rb', line 93 def self.low_r?(r) # https://github.com/bitcoin/bitcoin/blob/v0.20.0/src/key.cpp#L207 h = r.scan(/../) h[3].to_i(16) == 32 and h[4].to_i(16) < 0x80 end |
.pinToAesKey(secret_pin, iterations = 2048) ⇒ Object
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/block_io/helper.rb', line 68 def self.pinToAesKey(secret_pin, iterations = 2048) # converts the pincode string to PBKDF2 # returns a base64 version of PBKDF2 pincode salt = "" part1 = OpenSSL::PKCS5.pbkdf2_hmac( secret_pin, "", 1024, 128/8, OpenSSL::Digest::SHA256.new ).unpack("H*")[0] part2 = OpenSSL::PKCS5.pbkdf2_hmac( part1, "", 1024, 256/8, OpenSSL::Digest::SHA256.new ) # binary [part2].pack("m0") # the base64 encryption key end |
.sha256(value) ⇒ Object
63 64 65 66 |
# File 'lib/block_io/helper.rb', line 63 def self.sha256(value) # returns the hex of the hash of the given value OpenSSL::Digest::SHA256.digest(value).unpack("H*")[0] end |
.signData(inputs, keys) ⇒ Object
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/block_io/helper.rb', line 5 def self.signData(inputs, keys) # sign the given data with the given keys raise Exception.new("Keys object must be a hash or array containing the appropriate keys.") unless keys.size >= 1 signatures_added = false # create a dictionary of keys we have # saves the next loop from being O(n^3) hkeys = (keys.is_a?(Hash) ? keys : keys.inject({}){|h,v| h[v.public_key] = v; h}) odata = [] # saves the next loop from being O(n^2) inputs.each{|input| odata << input["data_to_sign"]; odata << input["signatures_needed"]; odata.push(*input["signers"])} data_to_sign = nil signatures_needed = nil while !(cdata = odata.shift).nil? do # O(n) if cdata.is_a?(String) then # this is data to sign # make a copy of this data_to_sign = '' << cdata # number of signatures needed signatures_needed = 0 + odata.shift else # add signatures if necessary # dTrust required signatures may be lower than number of keys provided if hkeys.key?(cdata["signer_public_key"]) and signatures_needed > 0 and cdata["signed_data"].nil? then cdata["signed_data"] = hkeys[cdata["signer_public_key"]].sign(data_to_sign) signatures_needed -= 1 signatures_added ||= true end end end signatures_added end |