proof_of_work 0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Gemfile +9 -0
- data/Gemfile.lock +33 -0
- data/README.md +11 -0
- data/Rakefile +7 -0
- data/lib/proof_of_work.rb +76 -0
- data/proof_of_work.gemspec +15 -0
- data/test/proof_of_work_test.rb +13 -0
- metadata +81 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 000da3afd390eaf04fe6f51c600f93b7be937945
|
4
|
+
data.tar.gz: d7c0e267622a70aca871c6f2fb16837646d4dc60
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 2f69fa492e820633d987da82cffea1e509a1ddc756b4e6a6a101b32399c36e1366fb0023a58440f21e7f0c3edbb480aa4e89a23a655290c967a2f6db73c6456d
|
7
|
+
data.tar.gz: 637829568b0b91ff915a407088b3234ff7c70cc4155fb4fec40753d398e6154e1e9c4e389e611d1f708c8177fcd41d2b0565b7341e521c52432fefbda8a17dbb
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
proof_of_work (0.1)
|
5
|
+
|
6
|
+
GEM
|
7
|
+
remote: http://rubygems.org/
|
8
|
+
specs:
|
9
|
+
columnize (0.3.6)
|
10
|
+
debugger (1.6.5)
|
11
|
+
columnize (>= 0.3.1)
|
12
|
+
debugger-linecache (~> 1.2.0)
|
13
|
+
debugger-ruby_core_source (~> 1.3.1)
|
14
|
+
debugger-linecache (1.2.0)
|
15
|
+
debugger-ruby_core_source (1.3.1)
|
16
|
+
given_core (3.5.0)
|
17
|
+
sorcerer (>= 0.3.7)
|
18
|
+
minitest (5.2.2)
|
19
|
+
minitest-given (3.5.0)
|
20
|
+
given_core (= 3.5.0)
|
21
|
+
minitest (> 4.3)
|
22
|
+
rake (10.1.1)
|
23
|
+
sorcerer (1.0.2)
|
24
|
+
|
25
|
+
PLATFORMS
|
26
|
+
ruby
|
27
|
+
|
28
|
+
DEPENDENCIES
|
29
|
+
debugger
|
30
|
+
minitest (~> 5.2.2)
|
31
|
+
minitest-given (~> 3.5.0)
|
32
|
+
proof_of_work!
|
33
|
+
rake
|
data/README.md
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
require "openssl"
|
2
|
+
|
3
|
+
class ProofOfWork
|
4
|
+
VERSION = 1
|
5
|
+
|
6
|
+
class << self
|
7
|
+
def generate(identifier, options = {})
|
8
|
+
options[:now] ||= Time.now
|
9
|
+
options[:bits] ||= 20
|
10
|
+
options[:extension] ||= ""
|
11
|
+
options[:salt_chars] ||= 8
|
12
|
+
options[:stamp_seconds] ||= false
|
13
|
+
|
14
|
+
timestamp = if !!options[:stamp_seconds]
|
15
|
+
options[:now].strftime("%y%m%d%H%M%S")
|
16
|
+
else
|
17
|
+
options[:now].strftime("%y%m%d")
|
18
|
+
end
|
19
|
+
|
20
|
+
challenge = "%s:" * 6 % [
|
21
|
+
VERSION,
|
22
|
+
options[:bits],
|
23
|
+
timestamp,
|
24
|
+
identifier,
|
25
|
+
options[:extension],
|
26
|
+
salt(options[:salt_chars])
|
27
|
+
]
|
28
|
+
|
29
|
+
challenge + hashcash(challenge, options[:bits])
|
30
|
+
end
|
31
|
+
|
32
|
+
def valid?(stamp, options = {})
|
33
|
+
bits_claim, date, identifier, extension, rand, counter = stamp[0...2].split(":")
|
34
|
+
|
35
|
+
return false if options[:identifier] != identifier
|
36
|
+
return false if options[:bits].to_i > bits_claim.to_i
|
37
|
+
|
38
|
+
if options[:expiration]
|
39
|
+
return false if date < options[:expiration].strftime("%y%m%d%H%M%S")
|
40
|
+
end
|
41
|
+
|
42
|
+
hex_digits = (bits_claim.to_i/4.0).floor.to_i
|
43
|
+
|
44
|
+
sha1 = OpenSSL::Digest::SHA1.new
|
45
|
+
sha1 << stamp
|
46
|
+
|
47
|
+
sha1.hexdigest.start_with?("0" * hex_digits)
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def salt(length)
|
53
|
+
letters = [*("a".."z"), *("A".."Z"), "+", "/", "="]
|
54
|
+
length.times.map{ letters.sample }.join
|
55
|
+
end
|
56
|
+
|
57
|
+
def hashcash(challenge, bits)
|
58
|
+
hex_digits = (bits/4.0).ceil
|
59
|
+
zeros = "0" * hex_digits
|
60
|
+
counter = 0
|
61
|
+
|
62
|
+
loop do
|
63
|
+
sha1 = OpenSSL::Digest::SHA1.new
|
64
|
+
sha1 << challenge
|
65
|
+
sha1 << counter.to_s(16)
|
66
|
+
|
67
|
+
digest = sha1.hexdigest
|
68
|
+
section = digest[0...hex_digits]
|
69
|
+
|
70
|
+
return counter.to_s(16) if section == zeros
|
71
|
+
|
72
|
+
counter += 1
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = "proof_of_work"
|
3
|
+
s.version = "0.1"
|
4
|
+
s.summary = "Hashcash algorithm"
|
5
|
+
s.description = "Hashcash version 1 algorithm generator and checker"
|
6
|
+
s.authors = ["elcuervo"]
|
7
|
+
s.licenses = ["MIT", "HUGWARE"]
|
8
|
+
s.email = ["yo@brunoaguirre.com"]
|
9
|
+
s.homepage = "http://github.com/elcuervo/proof_of_work"
|
10
|
+
s.files = `git ls-files`.split("\n")
|
11
|
+
s.test_files = `git ls-files test`.split("\n")
|
12
|
+
|
13
|
+
s.add_development_dependency("minitest", "~> 5.2.2")
|
14
|
+
s.add_development_dependency("minitest-given", "~> 3.5.0")
|
15
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
$: << "lib"
|
2
|
+
|
3
|
+
require "minitest"
|
4
|
+
require "minitest/given"
|
5
|
+
require "minitest/autorun"
|
6
|
+
require "proof_of_work"
|
7
|
+
|
8
|
+
describe ProofOfWork do
|
9
|
+
context "The generated hash is valid?" do
|
10
|
+
When(:hashcash) { ProofOfWork.generate("test") }
|
11
|
+
Then { ProofOfWork.valid?(hashcash) == true }
|
12
|
+
end
|
13
|
+
end
|
metadata
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: proof_of_work
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: '0.1'
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- elcuervo
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-01-26 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: minitest
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 5.2.2
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 5.2.2
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: minitest-given
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 3.5.0
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 3.5.0
|
41
|
+
description: Hashcash version 1 algorithm generator and checker
|
42
|
+
email:
|
43
|
+
- yo@brunoaguirre.com
|
44
|
+
executables: []
|
45
|
+
extensions: []
|
46
|
+
extra_rdoc_files: []
|
47
|
+
files:
|
48
|
+
- Gemfile
|
49
|
+
- Gemfile.lock
|
50
|
+
- README.md
|
51
|
+
- Rakefile
|
52
|
+
- lib/proof_of_work.rb
|
53
|
+
- proof_of_work.gemspec
|
54
|
+
- test/proof_of_work_test.rb
|
55
|
+
homepage: http://github.com/elcuervo/proof_of_work
|
56
|
+
licenses:
|
57
|
+
- MIT
|
58
|
+
- HUGWARE
|
59
|
+
metadata: {}
|
60
|
+
post_install_message:
|
61
|
+
rdoc_options: []
|
62
|
+
require_paths:
|
63
|
+
- lib
|
64
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
70
|
+
requirements:
|
71
|
+
- - '>='
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: '0'
|
74
|
+
requirements: []
|
75
|
+
rubyforge_project:
|
76
|
+
rubygems_version: 2.0.3
|
77
|
+
signing_key:
|
78
|
+
specification_version: 4
|
79
|
+
summary: Hashcash algorithm
|
80
|
+
test_files:
|
81
|
+
- test/proof_of_work_test.rb
|