toy-ore 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. checksums.yaml +7 -0
  2. data/lib/toy_ore/scheme.rb +193 -0
  3. data/lib/toy_ore.rb +2 -0
  4. metadata +102 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: c57cc63d9ef567689c02c61ff7bc7b96116be43d6bc3dc439f799c6994fc7809
4
+ data.tar.gz: ebf214fa64fc581e8f66187360cd60ea34524d2482f176f3876db5580fbf1e6b
5
+ SHA512:
6
+ metadata.gz: 14e619355df2d705b0a44babe95ddbb871add95a11a8b0bd693b2a59c8d7ba26f3e1007beb3432ff6e82a56e9faa691aa18846fddb383c48435b1adc854bf980
7
+ data.tar.gz: ff6badcdb167a2e76a666edf57350c2639c78b66db77e07c8bcb211636b2a65e8327ee1fbc563a5112fe9afe7484bb6438d6a2176810125b2ae2804ab8d9bd9a
@@ -0,0 +1,193 @@
1
+ module ToyOre
2
+ module Scheme
3
+ # Encrypts a comparison result by XOR'ing the iv and key. Then XORing that result with the comparaison result.
4
+ #
5
+ # Uses an IV for non-determinism.
6
+ #
7
+ # A Boolean logic operation that compares two input bits and generates one output bit.
8
+ # If the bits are the same, the result is 0. If the bits are different, the result is 1.
9
+ # ^ represents the xor operator
10
+ #
11
+ # @param iv [Integer]
12
+ #
13
+ # @param key [Integer]
14
+ #
15
+ # @param cmp_result [Integer] -1, 0, 1
16
+ #
17
+ # @return [Integer]
18
+ def self.encrypt(iv, key, cmp_result)
19
+ (iv ^ key) ^ cmp_result
20
+ # binding.pry
21
+ end
22
+
23
+ # Compares 2 plaintexts and returns a cmp_result.
24
+ # If a < b -1
25
+ # If a == b 0
26
+ # if a > b 1
27
+ #
28
+ # @param a [Integer] A plaintext integer value
29
+ #
30
+ # @param b [Integer] A plaintext integer value
31
+ #
32
+ # @return cmp_result [Integer] The comparison result
33
+ def self.compare_plaintexts(a, b)
34
+ if a < b
35
+ return -1
36
+ elsif a == b
37
+ return 0
38
+ else
39
+ return 1
40
+ end
41
+ end
42
+
43
+ # Compares the left part of a ciphertext with the right part of a ciphertext,
44
+ # created by the same ore client. egToyOre::Scheme::OreScheme.new()
45
+ #
46
+ # @param left_ciphertext [Object]
47
+ #
48
+ # @param right_ciphertext [Object]
49
+ #
50
+ #
51
+ # @ return [Integer] The comparison result
52
+ # -1 if the left ciphertext is less than the right ciphertext
53
+ #
54
+ # 0 if the left ciphertext is equal to the right ciphertext
55
+ #
56
+ # 1 if the left ciphertext is greater than the right ciphertext
57
+ #
58
+ # To get the comparison result:
59
+ # We need the iv from the right ciphertext.
60
+ # The key from the left ciphertext.
61
+ # The value at the index of the offset from the left ciphertext, in the right ciphertext's encryption array.
62
+ # When we Xor the iv and key, with the encrypted value we get the comparison result
63
+
64
+ # eg
65
+ # [1] pry(ToyOre::Scheme)> iv
66
+ # => 416
67
+ # [2] pry(ToyOre::Scheme)> key
68
+ # => 208
69
+ # [3] pry(ToyOre::Scheme)> iv ^ key
70
+ # => 368
71
+ # [4] pry(ToyOre::Scheme)> (iv ^ key) ^ cmp_result
72
+ # => -369
73
+ # [5] pry(ToyOre::Scheme)> (iv ^ key) ^ -369
74
+ # => -1
75
+ def self.compare_ciphertexts(left_ciphertext, right_ciphertext)
76
+ (right_ciphertext.iv ^ left_ciphertext.key) ^ right_ciphertext.encryptions[left_ciphertext.offset]
77
+ end
78
+
79
+ class LeftCiphertext
80
+ attr_reader :offset, :key
81
+
82
+ def initialize(offset, key)
83
+ @offset = offset
84
+ @key = key
85
+ end
86
+
87
+ def <=>(right_ciphertext)
88
+ ToyOre::Scheme.compare_ciphertexts(self, right_ciphertext)
89
+ end
90
+ end
91
+
92
+ class RightCiphertext
93
+ attr_reader :iv, :encryptions
94
+
95
+ def initialize(iv, encryptions)
96
+ @iv = iv
97
+ @encryptions = encryptions
98
+ end
99
+
100
+ def <=>(left_ciphertext)
101
+ ToyOre::Scheme.compare_ciphertexts(left_ciphertext, self)
102
+ end
103
+ end
104
+
105
+ class OreCiphertext
106
+ attr_reader :left, :right
107
+
108
+ def initialize(offset, key, iv, encryptions)
109
+ @left = LeftCiphertext.new(offset, key)
110
+ @right = RightCiphertext.new(iv, encryptions)
111
+ end
112
+ end
113
+
114
+ class OreScheme
115
+ def initialize
116
+ # Highlight that these are secrets.
117
+ # PRF key
118
+ @keys = (0..255).to_a.shuffle()
119
+ # PRP key
120
+ @prp = (0..255).to_a.shuffle()
121
+ end
122
+
123
+ def encrypt(plaintext)
124
+ iv = rand(0..255)
125
+ # This represents all the values in the domain.
126
+
127
+ # This is a small domain example.
128
+ # This is 1 block, 1 byte, 8 bits, total value is 256.
129
+ domain = (0..255).to_a
130
+
131
+ # Array to hold the encrypted value of the cmp result for each value in the domain.
132
+ encryptions = []
133
+
134
+ domain.each do |d|
135
+ # The offset is what ever index d (the plaintext) is in the shuffled PRP array.
136
+ # If we used the plaintext value as the offset, this would give away the value of the plaintext.
137
+ # Using the PRP, swaps the plaintext value for a random number in the PRP to store the encrypted
138
+ # comparison result in the right ciphertext encryptions array.
139
+ offset = @prp[d]
140
+
141
+ # Compare the domain value to the plaintext value
142
+ # We get -1, 0 or 1 here.
143
+ cmp_result = ToyOre::Scheme.compare_plaintexts(d, plaintext)
144
+
145
+ # At index offset in the encryptions array
146
+ # set the xor'd value of (iv and value) xor'd with the cmp result
147
+ # to the index at the offset value.
148
+
149
+ # We store the encrypted value of the comparison result
150
+ # in the encryptions array
151
+ # at the index = to the offset.
152
+ #
153
+ # To encrypt we pass the random iv, the key is the value at the offset index in the
154
+ # random shuffled key array.
155
+ #
156
+ #
157
+ encryptions[offset] = ToyOre::Scheme.encrypt(iv, @keys[offset], cmp_result)
158
+ end
159
+
160
+ # The left ciphertext:
161
+ # Query ciphertext
162
+ # 1. Stores the value of the offset.
163
+
164
+ # The offset is the index of the encrypted comparison result,
165
+ # in the encryptions array.
166
+ #
167
+ # 2. Stores the key that was used to encrypt the comparison result.
168
+ #
169
+ # The right ciphertext:
170
+ # Persisted
171
+ #
172
+ # 1. Stores the IV used in the encryption
173
+ # 2. Stores an array of all encrypted comparison results.
174
+ #
175
+ #
176
+ OreCiphertext.new(@prp[plaintext], @keys[@prp[plaintext]], iv, encryptions)
177
+ end
178
+ end
179
+ end
180
+ end
181
+
182
+
183
+ # TODO make ciphertext a class.
184
+ # make left a class and right a class
185
+ # on the left ciphertext implement the comparison
186
+
187
+ # class LeftCiphertext
188
+ # def <=>(right_ciphertext)
189
+ # ToyOre::Scheme.compare_ciphertexts(self, right_ciphertext
190
+
191
+ # )
192
+ # end
193
+ # end
data/lib/toy_ore.rb ADDED
@@ -0,0 +1,2 @@
1
+ require "toy_ore/scheme"
2
+
metadata ADDED
@@ -0,0 +1,102 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: toy-ore
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - Fiona McCawley
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2023-02-02 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rspec
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '3.0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '3.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: pry
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: debug
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: 1.0.0
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: 1.0.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: pry-byebug
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: A toy library to get an understanding of how ore encryption works. This
70
+ is an unsafe implementation, only to be used for educational purposes. DO NOT USE
71
+ IN PRODUCTION.
72
+ email: fimccawley@gmail.com
73
+ executables: []
74
+ extensions: []
75
+ extra_rdoc_files: []
76
+ files:
77
+ - lib/toy_ore.rb
78
+ - lib/toy_ore/scheme.rb
79
+ homepage: https://rubygems.org/gems/toy-ore
80
+ licenses:
81
+ - MIT
82
+ metadata: {}
83
+ post_install_message:
84
+ rdoc_options: []
85
+ require_paths:
86
+ - lib
87
+ required_ruby_version: !ruby/object:Gem::Requirement
88
+ requirements:
89
+ - - ">="
90
+ - !ruby/object:Gem::Version
91
+ version: '0'
92
+ required_rubygems_version: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ requirements: []
98
+ rubygems_version: 3.1.6
99
+ signing_key:
100
+ specification_version: 4
101
+ summary: toy-ore
102
+ test_files: []