bitster 0.0.1c

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +7 -0
  2. data/.codeclimate.yml +4 -0
  3. data/.coveralls.yml +1 -0
  4. data/.gitignore +3 -0
  5. data/.rspec +2 -0
  6. data/.travis.yml +6 -0
  7. data/Gemfile +4 -0
  8. data/README.md +25 -0
  9. data/Rakefile +1 -0
  10. data/bitster.gemspec +37 -0
  11. data/coverage/.last_run.json +5 -0
  12. data/coverage/.resultset.json +363 -0
  13. data/coverage/.resultset.json.lock +0 -0
  14. data/coverage/assets/0.10.0/application.css +799 -0
  15. data/coverage/assets/0.10.0/application.js +1707 -0
  16. data/coverage/assets/0.10.0/colorbox/border.png +0 -0
  17. data/coverage/assets/0.10.0/colorbox/controls.png +0 -0
  18. data/coverage/assets/0.10.0/colorbox/loading.gif +0 -0
  19. data/coverage/assets/0.10.0/colorbox/loading_background.png +0 -0
  20. data/coverage/assets/0.10.0/favicon_green.png +0 -0
  21. data/coverage/assets/0.10.0/favicon_red.png +0 -0
  22. data/coverage/assets/0.10.0/favicon_yellow.png +0 -0
  23. data/coverage/assets/0.10.0/loading.gif +0 -0
  24. data/coverage/assets/0.10.0/magnify.png +0 -0
  25. data/coverage/assets/0.10.0/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  26. data/coverage/assets/0.10.0/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  27. data/coverage/assets/0.10.0/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  28. data/coverage/assets/0.10.0/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  29. data/coverage/assets/0.10.0/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  30. data/coverage/assets/0.10.0/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  31. data/coverage/assets/0.10.0/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  32. data/coverage/assets/0.10.0/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  33. data/coverage/assets/0.10.0/smoothness/images/ui-icons_222222_256x240.png +0 -0
  34. data/coverage/assets/0.10.0/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
  35. data/coverage/assets/0.10.0/smoothness/images/ui-icons_454545_256x240.png +0 -0
  36. data/coverage/assets/0.10.0/smoothness/images/ui-icons_888888_256x240.png +0 -0
  37. data/coverage/assets/0.10.0/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
  38. data/coverage/index.html +2290 -0
  39. data/examples/bitster.rb +58 -0
  40. data/examples/bitster.txt +9 -0
  41. data/examples/bitster_simple.rb +27 -0
  42. data/lib/bitster.rb +14 -0
  43. data/lib/bitster/crypto_math.rb +132 -0
  44. data/lib/bitster/rsa_key_pair.rb +87 -0
  45. data/lib/bitster/rsa_machine.rb +32 -0
  46. data/lib/bitster/rsa_private_key.rb +31 -0
  47. data/lib/bitster/rsa_pub_key.rb +28 -0
  48. data/lib/bitster/var_helpers.rb +13 -0
  49. data/lib/bitster/version.rb +3 -0
  50. metadata +232 -0
@@ -0,0 +1,58 @@
1
+ $dev = true # flip this if running against an actually installed gem
2
+
3
+ if !$dev
4
+ require 'bitster'
5
+ else
6
+ require_relative '../lib/bitster/version'
7
+ require_relative '../lib/bitster/crypto_math'
8
+ require_relative '../lib/bitster/var_helpers'
9
+ require_relative '../lib/bitster/rsa_key_pair'
10
+ require_relative '../lib/bitster/rsa_pub_key'
11
+ require_relative '../lib/bitster/rsa_private_key'
12
+ require_relative '../lib/bitster/rsa_machine'
13
+ end
14
+
15
+ ciphertext = Array.new
16
+ result = Array.new
17
+
18
+ begin
19
+ plaintext = File.read(ARGV[0]).split("")
20
+ rescue
21
+ if $stdin.tty?
22
+ plaintext = ("C"*32).split("")
23
+ else
24
+ plaintext = ARGF.read.split("")
25
+ end
26
+ end
27
+
28
+ key_len = 1024
29
+ print "[*] Generating a new RSA key-pair with modulus #{key_len}..."
30
+ t0 = Time.now.to_i
31
+ pair = Bitster::RSAKeyPair.new(key_len)
32
+ t1 = Time.now.to_i
33
+ puts " done; time elapsed: #{t1 - t0}s."
34
+
35
+ machine = Bitster::RSAMachine.new(:keypair => pair)
36
+
37
+ print "[*] Encrypting..."
38
+ t0 = Time.now.to_i
39
+ plaintext.each do |c|
40
+ ciphertext << machine.encrypt(c.ord)
41
+ end
42
+ t1 = Time.now.to_i
43
+ puts " done; time elapsed: #{t1 - t0}s."
44
+
45
+
46
+ print "[*] Decrypting..."
47
+ t0 = Time.now.to_i
48
+ ciphertext.each do |c|
49
+ result << machine.decrypt(c).chr
50
+ end
51
+ t1 = Time.now.to_i
52
+ puts " done; time elapsed: #{t1 - t0}s."
53
+
54
+ puts "[*] Result:"
55
+ puts "-"*80
56
+ puts result.join
57
+ puts "-"*80
58
+ puts "[*] -END-"
@@ -0,0 +1,9 @@
1
+ RSA is one of the first practical public-key cryptosystems and is widely used
2
+ for secure data transmission. In such a cryptosystem, the encryption key is
3
+ public and differs from the decryption key which is kept secret. In RSA, this
4
+ asymmetry is based on the practical difficulty of factoring the product of two
5
+ large prime numbers, the factoring problem. RSA is made of the initial letters
6
+ of the surnames of Ron Rivest, Adi Shamir, and Leonard Adleman, who first
7
+ publicly described the algorithm in 1977. Clifford Cocks, an English mathe-
8
+ matician working for the UK intelligence agency GCHQ, had developed an equi-
9
+ valent system in 1973, but it was not declassified until 1997.
@@ -0,0 +1,27 @@
1
+ $dev = true # flip this if running against an actually installed gem
2
+
3
+ if !$dev
4
+ require 'bitster'
5
+ else
6
+ require_relative '../lib/bitster/version'
7
+ require_relative '../lib/bitster/crypto_math'
8
+ require_relative '../lib/bitster/var_helpers'
9
+ require_relative '../lib/bitster/rsa_key_pair'
10
+ require_relative '../lib/bitster/rsa_pub_key'
11
+ require_relative '../lib/bitster/rsa_private_key'
12
+ require_relative '../lib/bitster/rsa_machine'
13
+ end
14
+
15
+ key_pair = Bitster::RSAKeyPair.new(1024)
16
+ machine = Bitster::RSAMachine.new(:keypair => key_pair)
17
+
18
+ ciphertext = %w(H E L L O).collect do |char|
19
+ machine.encrypt(char.ord)
20
+ end
21
+
22
+ plaintext = ciphertext.collect do |ascii_code|
23
+ machine.decrypt(ascii_code).chr
24
+ end.join('')
25
+
26
+ puts plaintext
27
+
@@ -0,0 +1,14 @@
1
+ require 'bitster/version'
2
+ require 'bitster/crypto_math'
3
+ require 'bitster/var_helpers'
4
+ require 'bitster/rsa_key_pair'
5
+ require 'bitster/rsa_pub_key'
6
+ require 'bitster/rsa_private_key'
7
+ require 'bitster/rsa_machine'
8
+
9
+
10
+ require 'json'
11
+
12
+ module Bitster
13
+ include self::CryptoMath
14
+ end
@@ -0,0 +1,132 @@
1
+ module Bitster
2
+
3
+ # This module implements mathematical functions needed by the RSA layer,
4
+ # i.e. primality tests, modular arithmetic, and random odd number generation.
5
+ #
6
+ # ToDo: Error handling (with custom Exception class, etc.)
7
+ #
8
+ module CryptoMath
9
+
10
+ # This function performs what is known as Modular exponentiation
11
+ # https://en.wikipedia.org/wiki/Modular_exponentiation
12
+ #
13
+ # Modular exponentiation are easy to compute, even when the numbers
14
+ # involved are enormous.
15
+ #
16
+ def modular_pow(base, exponent, modulus)
17
+ return nil if modulus == 1
18
+ result = 1
19
+ base = base % modulus
20
+ while exponent > 0 do
21
+ if (exponent % 2) == 1
22
+ result = (result * base) % modulus
23
+ end
24
+ exponent = exponent >> 1
25
+ base = (base * base) % modulus
26
+ end
27
+ result
28
+ end
29
+
30
+ # This function just combines Fermat test and Rabin-Miller test.
31
+ # If both witness the primality, we consider the argument a
32
+ # probable prime
33
+ #
34
+ # ToDo: How to calculate an optimal number of RM rounds instead of 7?
35
+ #
36
+ def probable_prime?(p, k=7)
37
+ fermat_prime?(p) && rm_prime?(p, k)
38
+ end
39
+
40
+ # This is Fermat primality test.
41
+ # https://en.wikipedia.org/wiki/Fermat_primality_test
42
+ #
43
+ # ToDo: How to really choose "a" and how many iterations to run?
44
+ #
45
+ def fermat_prime?(p)
46
+ raise ArgumentError, 'Argument must be an Integer greater than 3' unless p.is_a?(Integer) && (p>3)
47
+ [p-1, p/2, p/3, p/4, 1].each do |a|
48
+ # return false if (a**(p-1) % p) != (1 % p)
49
+ return false if modular_pow(a, (p-1), p) != (1 % p)
50
+ end
51
+ true
52
+ end
53
+
54
+ # This is Rabin-Miller primality test
55
+ # https://en.wikipedia.org/wiki/Miller%E2%80%93Rabin_primality_test
56
+ #
57
+ def rm_prime?(n, k)
58
+ r=0; d=0
59
+ (1..128).each do |i|
60
+ d = n / (2**i)
61
+ r = i
62
+ break unless (d % 2) == 0
63
+ end
64
+ k.times do
65
+ flg = false
66
+ a = rand(2..(n-2))
67
+ x = modular_pow(a, d, n)
68
+ if (x == 1) || (x == (n - 1))
69
+ next
70
+ end
71
+ (r-1).times do
72
+ x = modular_pow(x, 2, n)
73
+ return false if x == 1
74
+ if x == (n - 1)
75
+ flg = true
76
+ break
77
+ end
78
+ end
79
+ next if flg
80
+ return false
81
+ end
82
+ true
83
+ end
84
+
85
+ # This function generates a random odd integer in a range of
86
+ # 2^(bits-1) ... 2^(bits)
87
+ #
88
+ # ToDo: What should the minimum really be?
89
+ #
90
+ def gen_odd(bits)
91
+ max = 2**bits
92
+ min = 2**(bits-1)
93
+ r = rand(min..max)
94
+ return r - 1 if r%2 == 0
95
+ r
96
+ end
97
+
98
+ # This function calculates the Modular multiplicative inverse
99
+ # which is needed in the key generation process.
100
+ # https://en.wikipedia.org/wiki/Modular_multiplicative_inverse
101
+ #
102
+ def modular_multiplicative_inverse(a, n)
103
+ t = 0
104
+ nt = 1
105
+ r = n
106
+ nr = a % n
107
+
108
+ if n < 0
109
+ n = -n
110
+ end
111
+ if a < 0
112
+ a = n - (-a % n)
113
+ end
114
+ while nr != 0 do
115
+ quot = 0
116
+ quot = (r/nr) unless (r/nr) == 0
117
+ tmp = nt; nt = t - quot*nt; t = tmp
118
+ tmp = nr; nr = r - quot*nr; r = tmp
119
+ end
120
+ if r > 1
121
+ raise StandardError, "#{a} and #{n} are not coprimes, can't find MMI"
122
+ end
123
+ if t < 0
124
+ t += n
125
+ end
126
+ t
127
+ end
128
+
129
+ extend self
130
+
131
+ end
132
+ end
@@ -0,0 +1,87 @@
1
+ module Bitster
2
+
3
+ # This class represents a RSA key-pair. The most important feature is the
4
+ # generation of the key-pair, so it is an implementation of the process
5
+ # outlined in https://en.wikipedia.org/wiki/RSA_(cryptosystem)#Key_generation
6
+ #
7
+ class RSAKeyPair
8
+
9
+ class RSAKeyPairError < StandardError
10
+ end
11
+
12
+ attr_reader :len, :shorter, :p, :q, :n, :k, :e, :private_key, :public_key
13
+
14
+ def initialize(len)
15
+ @len = len
16
+
17
+ @shorter = rand(0..1)
18
+ @p = gen_p
19
+ @q = gen_q
20
+ @n = @p * @q # modulus
21
+ @k = gen_totient
22
+ @e = gen_e # pubkey exponent
23
+ @d = gen_d # prikey exponent
24
+
25
+ @private_key = RSAPrivateKey.new(@p, @q, @d, @len)
26
+ @public_key = RSAPubKey.new(@n, @e, @len)
27
+
28
+ end
29
+
30
+ private
31
+ include CryptoMath
32
+
33
+ # ToDo: what should the length difference of p and q really be?
34
+ def gen_p
35
+ handle_exceptions do
36
+ len_p = @len/2
37
+ len_p -= rand(2..4) if @shorter == 0
38
+ loop do
39
+ p = gen_odd(len_p)
40
+ return p if probable_prime?(p)
41
+ end
42
+ end
43
+ end
44
+
45
+ # ToDo: what should the length difference of p and q really be?
46
+ def gen_q
47
+ handle_exceptions do
48
+ len_q = @len/2
49
+ len_q -= rand(2..4) if @shorter == 1
50
+ loop do
51
+ q = gen_odd(len_q)
52
+ return q if probable_prime?(q)
53
+ end
54
+ end
55
+ end
56
+
57
+ def gen_totient
58
+ handle_exceptions do
59
+ (@p-1)*(@q-1)
60
+ end
61
+ end
62
+
63
+ # ToDo: what should the lower bound really be?
64
+ def gen_e
65
+ handle_exceptions do
66
+ loop do
67
+ e = rand(4..@k)
68
+ return e if e.gcd(@k) == 1
69
+ end
70
+ end
71
+ end
72
+
73
+ def gen_d
74
+ handle_exceptions do
75
+ modular_multiplicative_inverse(e, k)
76
+ end
77
+ end
78
+
79
+ def handle_exceptions
80
+ begin
81
+ yield
82
+ rescue StandardError => e
83
+ raise RSAKeyPairError, "Exception in RSAKeyPair: #{e}"
84
+ end
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,32 @@
1
+ module Bitster
2
+
3
+ # This class implements RSA encryption and decryption functions.
4
+ # It is initialized with necessary keys, represented as instances
5
+ # of their according classes.
6
+ #
7
+ class RSAMachine
8
+ attr_accessor :pubkey, :prikey
9
+
10
+ def initialize(opts={})
11
+ @pubkey = opts[:pubkey] if opts.has_key?(:pubkey)
12
+ @prikey = opts[:prikey] if opts.has_key?(:prikey)
13
+ if opts.has_key?(:keypair)
14
+ @pubkey = opts[:keypair].public_key
15
+ @prikey = opts[:keypair].private_key
16
+ end
17
+ end
18
+
19
+ # https://en.wikipedia.org/wiki/RSA_(cryptosystem)#Encryption
20
+ #
21
+ def encrypt(plaintext_msg_code)
22
+ CryptoMath::modular_pow(plaintext_msg_code, @pubkey.exponent, @pubkey.modulus)
23
+ end
24
+
25
+ # https://en.wikipedia.org/wiki/RSA_(cryptosystem)#Decryption
26
+ #
27
+ def decrypt(ciphertext_msg_code)
28
+ CryptoMath::modular_pow(ciphertext_msg_code, @prikey.exponent, @prikey.modulus)
29
+ end
30
+
31
+ end
32
+ end
@@ -0,0 +1,31 @@
1
+ module Bitster
2
+
3
+ # This class represents RSA private key and provides various
4
+ # formatting and similar helper methods associated with it.
5
+ #
6
+ class RSAPrivateKey
7
+
8
+ attr_reader :modulus, :exponent, :len, :p, :q
9
+
10
+ def initialize(p, q, exponent, len)
11
+ @exponent = exponent
12
+ @modulus = p*q
13
+ @p = p; @q = q
14
+ @len = len
15
+ end
16
+
17
+ def get_hash
18
+ { modulus: pad(@modulus, 16, @len), exponent: pad(@exponent, 16, @len) }
19
+ end
20
+
21
+ def get_json
22
+ JSON.pretty_generate get_hash
23
+ end
24
+
25
+ private
26
+ include VarHelpers
27
+
28
+ end
29
+ end
30
+
31
+
@@ -0,0 +1,28 @@
1
+ module Bitster
2
+
3
+ # This class represents RSA public key and provides various
4
+ # formatting and similar helper methods associated with it.
5
+ #
6
+ class RSAPubKey
7
+
8
+ attr_reader :modulus, :exponent, :len
9
+
10
+ def initialize(modulus, exponent, len)
11
+ @modulus = modulus
12
+ @exponent = exponent
13
+ @len = len
14
+ end
15
+
16
+ def get_hash
17
+ { modulus: pad(@modulus, 16, @len), exponent: pad(@exponent, 16, @len) }
18
+ end
19
+
20
+ def get_json
21
+ JSON.pretty_generate get_hash
22
+ end
23
+
24
+ private
25
+ include VarHelpers
26
+
27
+ end
28
+ end
@@ -0,0 +1,13 @@
1
+ module Bitster
2
+ module VarHelpers
3
+ include Math
4
+
5
+ def pad(num, base, len)
6
+ digits = (len*log(2)) / (log(base))
7
+ num.to_s(base).rjust(digits, '0')
8
+ end
9
+
10
+ extend self
11
+
12
+ end
13
+ end
@@ -0,0 +1,3 @@
1
+ module Bitster
2
+ VERSION='0.0.1c'
3
+ end