Module: EasyPow

Defined in:
lib/easy_pow.rb,
lib/easy_pow/version.rb,
ext/easy_pow/ext.c

Constant Summary collapse

VERSION =
"0.1.2"
@@hashes =
[
  ['sha1', 160],
  ['md5', 128],
  ['sha224', 224],
  ['sha256', 256],
  ['sha384', 384],
  ['sha512', 512]
]

Class Method Summary collapse

Class Method Details

.easy_pow(bits, socket = nil) ⇒ Object



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/easy_pow.rb', line 44

def easy_pow(bits, socket = nil)
  in_s = out_s = socket
  if socket == nil
    in_s = STDIN
    out_s = STDOUT
  end
  prefix = SecureRandom.hex(8)
  out_s.print "Send me proof-of-work: The first #{bits}-bits of sha256(\"#{prefix}\" + input.rstrip) is \"111...1\"\n"
  out_s.flush
  input = in_s.gets.strip.force_encoding('ASCII-8BIT')
  digest = Digest::SHA256.digest(prefix + input.rstrip).unpack("C*")
  bits.times do |i|
    if (digest[i / 8] >> (7 - i % 8) & 1) == 0
      out_s.print "NG\n"
      out_s.flush
      return false
    end
  end
  out_s.print "OK\n"
  out_s.flush
  return true
end

.search_md5_ext(prefix, suffix, length, target, mask, chars, paralell) ⇒ Object



121
122
123
124
125
126
# File 'ext/easy_pow/ext.c', line 121

static VALUE search_md5(VALUE self, VALUE prefix, VALUE suffix, VALUE length, VALUE target, VALUE mask, VALUE chars, VALUE paralell) {
  struct search_condition cond;
  cond.hash = MD5;
  cond.md_len = 128 / 8;
  return search_general(self, prefix, suffix, length, target, mask, chars, paralell, &cond);
}

.search_prefix(hash, bin, length, prefix, suffix = '', chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', parallel = true) ⇒ Object

Raises:

  • (ArgumentError)


16
17
18
19
20
21
22
23
24
25
26
27
28
# File 'lib/easy_pow.rb', line 16

def search_prefix(hash, bin, length, prefix, suffix = '', chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', parallel = true)
  len = @@hashes.select{|a|a[0] == hash.to_s.downcase}[0]
  raise ArgumentError.new('Unknown hash type: %s' % [hash.to_s.downcase]) unless len
  len = len[1] / 8
  raise ArgumentError.new('Too long prefix') if bin.size > len * 8
  target = Array.new(len){0}
  mask = Array.new(len){0}
  bin.each_char.with_index do |b, i|
    mask[i / 8] |= 1 << (7 - i % 8)
    target[i / 8] |= b.to_i << (7 - i % 8)
  end
  send 'search_' + hash.to_s.downcase + '_ext', prefix, suffix, length, target.pack("C*"), mask.pack("C*"), chars, parallel
end

.search_sha1_ext(prefix, suffix, length, target, mask, chars, paralell) ⇒ Object



128
129
130
131
132
133
# File 'ext/easy_pow/ext.c', line 128

static VALUE search_sha1(VALUE self, VALUE prefix, VALUE suffix, VALUE length, VALUE target, VALUE mask, VALUE chars, VALUE paralell) {
  struct search_condition cond;
  cond.hash = SHA1;
  cond.md_len = 160 / 8;
  return search_general(self, prefix, suffix, length, target, mask, chars, paralell, &cond);
}

.search_sha224_ext(prefix, suffix, length, target, mask, chars, paralell) ⇒ Object



135
136
137
138
139
140
# File 'ext/easy_pow/ext.c', line 135

static VALUE search_sha224(VALUE self, VALUE prefix, VALUE suffix, VALUE length, VALUE target, VALUE mask, VALUE chars, VALUE paralell) {
  struct search_condition cond;
  cond.hash = SHA224;
  cond.md_len = 224 / 8;
  return search_general(self, prefix, suffix, length, target, mask, chars, paralell, &cond);
}

.search_sha256_ext(prefix, suffix, length, target, mask, chars, paralell) ⇒ Object



142
143
144
145
146
147
# File 'ext/easy_pow/ext.c', line 142

static VALUE search_sha256(VALUE self, VALUE prefix, VALUE suffix, VALUE length, VALUE target, VALUE mask, VALUE chars, VALUE paralell) {
  struct search_condition cond;
  cond.hash = SHA256;
  cond.md_len = 256 / 8;
  return search_general(self, prefix, suffix, length, target, mask, chars, paralell, &cond);
}

.search_sha384_ext(prefix, suffix, length, target, mask, chars, paralell) ⇒ Object



149
150
151
152
153
154
# File 'ext/easy_pow/ext.c', line 149

static VALUE search_sha384(VALUE self, VALUE prefix, VALUE suffix, VALUE length, VALUE target, VALUE mask, VALUE chars, VALUE paralell) {
  struct search_condition cond;
  cond.hash = SHA384;
  cond.md_len = 384 / 8;
  return search_general(self, prefix, suffix, length, target, mask, chars, paralell, &cond);
}

.search_sha512_ext(prefix, suffix, length, target, mask, chars, paralell) ⇒ Object



156
157
158
159
160
161
# File 'ext/easy_pow/ext.c', line 156

static VALUE search_sha512(VALUE self, VALUE prefix, VALUE suffix, VALUE length, VALUE target, VALUE mask, VALUE chars, VALUE paralell) {
  struct search_condition cond;
  cond.hash = SHA512;
  cond.md_len = 512 / 8;
  return search_general(self, prefix, suffix, length, target, mask, chars, paralell, &cond);
}

.search_suffix(hash, bin, length, prefix, suffix = '', chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', parallel = true) ⇒ Object

Raises:

  • (ArgumentError)


30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/easy_pow.rb', line 30

def search_suffix(hash, bin, length, prefix, suffix = '', chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', parallel = true)
  len = @@hashes.select{|a|a[0] == hash.to_s.downcase}[0]
  raise ArgumentError.new('Unknown hash type: %s' % [hash.to_s.downcase]) unless len
  len = len[1] / 8
  raise ArgumentError.new('Too long prefix') if bin.size > len * 8
  target = Array.new(len){0}
  mask = Array.new(len){0}
  bin.each_char.with_index do |b, i|
    mask[-(i / 8) - 1] |= 1 << (i % 8)
    target[-(i / 8) - 1] |= b.to_i << (i % 8)
  end
  send 'search_' + hash.to_s.downcase + '_ext', prefix, suffix, length, target.pack("C*"), mask.pack("C*"), chars, parallel
end

.solve(socket = nil) ⇒ Object



75
76
77
78
79
80
81
82
83
84
# File 'lib/easy_pow.rb', line 75

def solve(socket = nil)
  if socket.is_a?(String)
    return self.solve_line(input)
  else
    line = socket.gets
    socket.print solve_line(line) + "\n"
    socket.flush
    socket.gets == "OK\n"
  end
end

.solve_line(input) ⇒ Object



67
68
69
70
71
72
73
# File 'lib/easy_pow.rb', line 67

def solve_line(input)
  if /The first (\d+)-bits of sha256\("(.{16})"/ =~ input
    search_prefix('sha256', '1' * $1.to_i, 12, $2)[16..-1]
  else
    raise ArgumentError.new("Invalid format")
  end
end