toy-ore 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: []