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.
- checksums.yaml +7 -0
- data/lib/toy_ore/scheme.rb +193 -0
- data/lib/toy_ore.rb +2 -0
- 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
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: []
|