ore-rs 0.7.0-x86_64-darwin
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CODEOWNERS +2 -0
- data/CODE_OF_CONDUCT.md +49 -0
- data/CONTRIBUTING.md +10 -0
- data/LICENCE +124 -0
- data/README.md +72 -0
- data/ext/ore_rs/.gitignore +4 -0
- data/ext/ore_rs/Cargo.lock +741 -0
- data/ext/ore_rs/Cargo.toml +14 -0
- data/ext/ore_rs/extconf.rb +4 -0
- data/ext/ore_rs/src/lib.rs +142 -0
- data/lib/2.7/ore_rs.bundle +0 -0
- data/lib/3.0/ore_rs.bundle +0 -0
- data/lib/3.1/ore_rs.bundle +0 -0
- data/lib/ore/aes128/ciphertext.rb +47 -0
- data/lib/ore/aes128.rb +204 -0
- data/lib/ore/version.rb +3 -0
- data/lib/ore-rs.rb +15 -0
- data/ore-rs.gemspec +43 -0
- metadata +241 -0
@@ -0,0 +1,14 @@
|
|
1
|
+
[package]
|
2
|
+
name = "ore-rs"
|
3
|
+
version = "0.0.0"
|
4
|
+
edition = "2021"
|
5
|
+
|
6
|
+
[dependencies]
|
7
|
+
lazy_static = "^0.2.2"
|
8
|
+
ore-rs = "^0.6.0"
|
9
|
+
ore-encoding-rs = { git = "https://github.com/cipherstash/ore_encoding.rs" }
|
10
|
+
rb-sys = "0.8.0"
|
11
|
+
rutie = { git = "https://github.com/mpalmer/rutie", branch = "rb_sys" }
|
12
|
+
|
13
|
+
[lib]
|
14
|
+
crate-type = ["cdylib"]
|
@@ -0,0 +1,142 @@
|
|
1
|
+
#[macro_use]
|
2
|
+
extern crate rutie;
|
3
|
+
|
4
|
+
#[macro_use]
|
5
|
+
extern crate lazy_static;
|
6
|
+
|
7
|
+
use ore_encoding_rs::OrePlaintext;
|
8
|
+
use ore_rs::{CipherText, ORECipher, OREEncrypt};
|
9
|
+
use ore_rs::scheme::bit2::OREAES128;
|
10
|
+
use rutie::{Boolean, Class, Encoding, Float, Integer, Module, Object, RString, VerifiedObject, VM};
|
11
|
+
use std::cmp::Ordering;
|
12
|
+
|
13
|
+
module!(RbORE);
|
14
|
+
class!(RbOREAES128);
|
15
|
+
class!(RbOREAES128Ciphertext);
|
16
|
+
|
17
|
+
impl VerifiedObject for RbOREAES128Ciphertext {
|
18
|
+
fn is_correct_type<T: Object>(object: &T) -> bool {
|
19
|
+
let klass = Module::from_existing("ORE").get_nested_class("AES128").get_nested_class("Ciphertext");
|
20
|
+
klass.case_equals(object)
|
21
|
+
}
|
22
|
+
|
23
|
+
fn error_message() -> &'static str {
|
24
|
+
"Error converting to ORE::AES128::Ciphertext"
|
25
|
+
}
|
26
|
+
}
|
27
|
+
|
28
|
+
impl From<CipherText<OREAES128, 8>> for RbOREAES128Ciphertext {
|
29
|
+
fn from(ct: CipherText<OREAES128, 8>) -> Self {
|
30
|
+
let klass = Module::from_existing("ORE").get_nested_class("AES128").get_nested_class("Ciphertext");
|
31
|
+
klass.wrap_data(OreAes128Ciphertext { ct: ct.to_bytes(), n: 8 }, &*OREAES128_CIPHERTEXT_WRAPPER)
|
32
|
+
}
|
33
|
+
}
|
34
|
+
|
35
|
+
pub struct OreAes128 {
|
36
|
+
cipher: OREAES128
|
37
|
+
}
|
38
|
+
|
39
|
+
wrappable_struct!(OreAes128, OreAes128Wrapper, OREAES128_WRAPPER);
|
40
|
+
|
41
|
+
pub struct OreAes128Ciphertext {
|
42
|
+
#[allow(dead_code)]
|
43
|
+
n: u32,
|
44
|
+
ct: Vec<u8>
|
45
|
+
}
|
46
|
+
|
47
|
+
wrappable_struct!(OreAes128Ciphertext, OreAes128CiphertextWrapper, OREAES128_CIPHERTEXT_WRAPPER);
|
48
|
+
|
49
|
+
methods!(
|
50
|
+
RbOREAES128,
|
51
|
+
rbself,
|
52
|
+
|
53
|
+
fn ore_aes128_new(k1string: RString, k2string: RString) -> RbOREAES128 {
|
54
|
+
let mut k1: [u8; 16] = Default::default();
|
55
|
+
let mut k2: [u8; 16] = Default::default();
|
56
|
+
|
57
|
+
k1.clone_from_slice(k1string.unwrap().to_bytes_unchecked());
|
58
|
+
k2.clone_from_slice(k2string.unwrap().to_bytes_unchecked());
|
59
|
+
|
60
|
+
let cipher: OREAES128 = ORECipher::init(&k1, &k2).unwrap();
|
61
|
+
|
62
|
+
let klass = Module::from_existing("ORE").get_nested_class("AES128");
|
63
|
+
return klass.wrap_data(OreAes128 { cipher: cipher }, &*OREAES128_WRAPPER);
|
64
|
+
}
|
65
|
+
|
66
|
+
fn ore_aes128_encrypt_u64(plaintext: Integer) -> RbOREAES128Ciphertext {
|
67
|
+
let ore = rbself.get_data_mut(&*OREAES128_WRAPPER);
|
68
|
+
plaintext.unwrap().to_u64().encrypt(&mut ore.cipher).map_err(|e| VM::raise(Class::from_existing("RuntimeError"), &format!("Failed to encrypt ORE plaintext: {:?}", e))).unwrap().into()
|
69
|
+
}
|
70
|
+
|
71
|
+
fn ore_aes128_encrypt_f64(plaintext: Float) -> RbOREAES128Ciphertext {
|
72
|
+
let ore = rbself.get_data_mut(&*OREAES128_WRAPPER);
|
73
|
+
OrePlaintext::<u64>::from(plaintext.unwrap().to_f64()).0.encrypt(&mut ore.cipher).map_err(|e| VM::raise(Class::from_existing("RuntimeError"), &format!("Failed to encrypt ORE plaintext: {:?}", e))).unwrap().into()
|
74
|
+
}
|
75
|
+
|
76
|
+
fn ore_aes128_encrypt_string(plaintext: RString) -> RbOREAES128Ciphertext {
|
77
|
+
let ore = rbself.get_data_mut(&*OREAES128_WRAPPER);
|
78
|
+
OrePlaintext::<u64>::from(plaintext.unwrap().to_string_unchecked()).0.encrypt(&mut ore.cipher).map_err(|e| VM::raise(Class::from_existing("RuntimeError"), &format!("Failed to encrypt ORE plaintext: {:?}", e))).unwrap().into()
|
79
|
+
}
|
80
|
+
|
81
|
+
fn ore_aes128_encrypt_bool(plaintext: Boolean) -> RbOREAES128Ciphertext {
|
82
|
+
let ore = rbself.get_data_mut(&*OREAES128_WRAPPER);
|
83
|
+
OrePlaintext::<u64>::from(plaintext.unwrap().to_bool()).0.encrypt(&mut ore.cipher).map_err(|e| VM::raise(Class::from_existing("RuntimeError"), &format!("Failed to encrypt ORE plaintext: {:?}", e))).unwrap().into()
|
84
|
+
}
|
85
|
+
);
|
86
|
+
|
87
|
+
methods!(
|
88
|
+
RbOREAES128Ciphertext,
|
89
|
+
rbself,
|
90
|
+
|
91
|
+
fn ore_aes128_ciphertext_new(serialized_ciphertext: RString, n: Integer) -> RbOREAES128Ciphertext {
|
92
|
+
let ct = CipherText::<OREAES128, 8>::from_bytes(&serialized_ciphertext.unwrap().to_vec_u8_unchecked()).map_err(|e| VM::raise(Class::from_existing("ArgumentError"), &format!("Failed to deserialize ORE ciphertext: {:?}", e))).unwrap();
|
93
|
+
|
94
|
+
let klass = Module::from_existing("ORE").get_nested_class("AES128").get_nested_class("Ciphertext");
|
95
|
+
return klass.wrap_data(OreAes128Ciphertext { ct: ct.to_bytes(), n: n.unwrap().to_u32() }, &*OREAES128_CIPHERTEXT_WRAPPER);
|
96
|
+
}
|
97
|
+
|
98
|
+
fn ore_aes128_ciphertext_serialize() -> RString {
|
99
|
+
let obj = rbself.get_data(&*OREAES128_CIPHERTEXT_WRAPPER);
|
100
|
+
|
101
|
+
return RString::from_bytes(&obj.ct, &Encoding::find("BINARY").unwrap());
|
102
|
+
}
|
103
|
+
|
104
|
+
fn ore_aes128_ciphertext_cmp(other: RbOREAES128Ciphertext) -> Integer {
|
105
|
+
let obj = rbself.get_data(&*OREAES128_CIPHERTEXT_WRAPPER);
|
106
|
+
let real_other = other.unwrap();
|
107
|
+
let oth = real_other.get_data(&*OREAES128_CIPHERTEXT_WRAPPER);
|
108
|
+
|
109
|
+
match OREAES128::compare_raw_slices(&obj.ct, &oth.ct) {
|
110
|
+
Some(Ordering::Equal) => Integer::from(0),
|
111
|
+
Some(Ordering::Less) => Integer::from(-1),
|
112
|
+
Some(Ordering::Greater) => Integer::from(1),
|
113
|
+
None => {
|
114
|
+
VM::raise(Class::from_existing("RuntimeError"), "Comparison failed");
|
115
|
+
Integer::from(0)
|
116
|
+
}
|
117
|
+
}
|
118
|
+
}
|
119
|
+
);
|
120
|
+
|
121
|
+
|
122
|
+
|
123
|
+
|
124
|
+
#[allow(non_snake_case)]
|
125
|
+
#[no_mangle]
|
126
|
+
pub extern "C" fn Init_ore_rs() {
|
127
|
+
Module::from_existing("ORE").define(|oremod| {
|
128
|
+
oremod.define_nested_class("AES128", None).define(|cipher_class| {
|
129
|
+
cipher_class.singleton_class().def_private("_new", ore_aes128_new);
|
130
|
+
cipher_class.def_private("_encrypt_u64", ore_aes128_encrypt_u64);
|
131
|
+
cipher_class.def_private("_encrypt_f64", ore_aes128_encrypt_f64);
|
132
|
+
cipher_class.def_private("_encrypt_string", ore_aes128_encrypt_string);
|
133
|
+
cipher_class.def_private("_encrypt_bool", ore_aes128_encrypt_bool);
|
134
|
+
|
135
|
+
cipher_class.define_nested_class("Ciphertext", None).define(|ciphertext_class| {
|
136
|
+
ciphertext_class.singleton_class().def_private("_new", ore_aes128_ciphertext_new);
|
137
|
+
ciphertext_class.def_private("_serialize", ore_aes128_ciphertext_serialize);
|
138
|
+
ciphertext_class.def_private("_cmp", ore_aes128_ciphertext_cmp);
|
139
|
+
});
|
140
|
+
});
|
141
|
+
});
|
142
|
+
}
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module ORE
|
2
|
+
class AES128
|
3
|
+
# An ORE ciphertext produced by an AES128 cipher.
|
4
|
+
class Ciphertext
|
5
|
+
include Comparable
|
6
|
+
|
7
|
+
# Create a ciphertext object from a serialized form.
|
8
|
+
#
|
9
|
+
# ORE ciphertexts can be serialized (using #to_s), and then deserialized by
|
10
|
+
# passing them into this constructor.
|
11
|
+
#
|
12
|
+
# @param ct [String] the serialized ciphertext. This must be a `BINARY` encoded
|
13
|
+
# string.
|
14
|
+
#
|
15
|
+
# @param n [Integer] the number of ORE blocks contained in the ciphertext. Each
|
16
|
+
# ORE block represents one octet of the plaintext. At present, only 64-bit
|
17
|
+
# plaintexts are supported, so this must always be `8`.
|
18
|
+
#
|
19
|
+
# @raises [ArgumentError] if the string passed as the ciphertext is not valid,
|
20
|
+
# or `n` is not a supported value.
|
21
|
+
#
|
22
|
+
def self.new(ct, n)
|
23
|
+
unless ct.is_a?(String)
|
24
|
+
raise ArgumentError, "Ciphertext must be a string"
|
25
|
+
end
|
26
|
+
|
27
|
+
unless n == 8
|
28
|
+
raise ArgumentError, "Only a block count of 8 is currently supported"
|
29
|
+
end
|
30
|
+
|
31
|
+
_new(ct, n)
|
32
|
+
end
|
33
|
+
|
34
|
+
def to_s
|
35
|
+
_serialize
|
36
|
+
end
|
37
|
+
|
38
|
+
def <=>(other)
|
39
|
+
unless other.is_a?(ORE::AES128::Ciphertext)
|
40
|
+
raise ArgumentError, "Cannot compare an ORE ciphertext to anything other than another ciphertext"
|
41
|
+
end
|
42
|
+
|
43
|
+
_cmp(other)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
data/lib/ore/aes128.rb
ADDED
@@ -0,0 +1,204 @@
|
|
1
|
+
require "date"
|
2
|
+
|
3
|
+
require_relative "./aes128/ciphertext"
|
4
|
+
|
5
|
+
module ORE
|
6
|
+
class AES128
|
7
|
+
VALID_STRING_ENCODINGS = [Encoding.find("UTF-8"), Encoding.find("US-ASCII")]
|
8
|
+
private_constant :VALID_STRING_ENCODINGS
|
9
|
+
|
10
|
+
# Create a new ORE::AES128 "cipher" -- an object capable of encrypting plaintexts into ORE ciphertexts.
|
11
|
+
#
|
12
|
+
# @param k1 [String] also known as the "PRF key", this is one of the two keys required
|
13
|
+
# to encrypt with ORE. This key must be a 16 octet string in the `BINARY` encoding.
|
14
|
+
#
|
15
|
+
# @param k2 [String] also known as the "PRP key", this is the other of the two keys
|
16
|
+
# required to encrypt with ORE. This key must also be a 16 octet string in the `BINARY`
|
17
|
+
# encoding.
|
18
|
+
#
|
19
|
+
# @param b [Integer] the number of bits in each plaintext. At present, the only supported
|
20
|
+
# value for this parameter is `64`.
|
21
|
+
#
|
22
|
+
# @param n [Integer] the number of blocks to generate in the ORE ciphertext. Each block
|
23
|
+
# is derived from 8 bits of plaintext, and thus at present the only supported value
|
24
|
+
# for this parameter is `8`.
|
25
|
+
#
|
26
|
+
# @raises [ArgumentError] if any of the parameters do not meet the requirements.
|
27
|
+
#
|
28
|
+
def self.new(k1, k2, b, n)
|
29
|
+
validate_key(k1, "k1")
|
30
|
+
validate_key(k2, "k2")
|
31
|
+
|
32
|
+
unless b == 64
|
33
|
+
raise ArgumentError, "Only 64 bit ORE plaintexts are supported at present"
|
34
|
+
end
|
35
|
+
|
36
|
+
unless n == 8
|
37
|
+
raise ArgumentError, "Only 8 bit ORE blocks are supported at present"
|
38
|
+
end
|
39
|
+
|
40
|
+
_new(k1, k2, b, n)
|
41
|
+
end
|
42
|
+
|
43
|
+
# Encrypt a plaintext into an ORE::AES128::Ciphertext.
|
44
|
+
#
|
45
|
+
# @note the type of the object you pass in as the plaintext is crucially important.
|
46
|
+
# Different types of object are encoded incompatibly, and comparisons between
|
47
|
+
# ciphertexts generated from objects of different types is not guaranteed.
|
48
|
+
# For example, `#encrypt(-3.0) < #encrypt(1)` will not necessarily be true,
|
49
|
+
# even though `#encrypt(-3.0) < #encrypt(1.0)` is guaranteed.
|
50
|
+
#
|
51
|
+
# The currently supported types are:
|
52
|
+
#
|
53
|
+
# * `Integer` -- must be in the range 0..2**64-1 (inclusive). Will be encoded as
|
54
|
+
# an ORE `uint64`.
|
55
|
+
#
|
56
|
+
# * `Float` -- can be any double precision floating-point number, except for a NaN.
|
57
|
+
#
|
58
|
+
# * `String` -- any valid UTF-8 string. Will be hashed into a 64-bit value for storage.
|
59
|
+
#
|
60
|
+
# * `Range` -- a range of Integers, Floats, Dates, or Times; both ends must be of the
|
61
|
+
# same type. Indefinite beginnings *or* ends are supported, but not both.
|
62
|
+
#
|
63
|
+
# * `Date`, `Time` -- will be converted into milliseconds relative to the UTC epoch.
|
64
|
+
#
|
65
|
+
# @param plaintext [Integer, Float] the plaintext to encrypt.
|
66
|
+
#
|
67
|
+
# @raises [ArgumentError] if the type of the plaintext is not one currently supported,
|
68
|
+
# or the value of the plaintext is not one which is valid.
|
69
|
+
#
|
70
|
+
# @raises [RuntimeError] if a float is encrypted on a platform that doesn't use
|
71
|
+
# IEEE754 double-precision floating-point numbers as its representation of a
|
72
|
+
# `Float`, or if something spectacularly wrong happens in the ORE encryption process.
|
73
|
+
#
|
74
|
+
def encrypt(plaintext)
|
75
|
+
case plaintext
|
76
|
+
when Integer
|
77
|
+
encrypt_u64(plaintext)
|
78
|
+
when Float
|
79
|
+
encrypt_f64(plaintext)
|
80
|
+
when String
|
81
|
+
encrypt_string(plaintext)
|
82
|
+
when TrueClass, FalseClass
|
83
|
+
encrypt_bool(plaintext)
|
84
|
+
when Range
|
85
|
+
encrypt_range(plaintext)
|
86
|
+
when Date
|
87
|
+
encrypt(plaintext.to_time)
|
88
|
+
when Time
|
89
|
+
encrypt_time(plaintext)
|
90
|
+
else
|
91
|
+
raise ArgumentError, "Do not know how to ORE encrypt a #{plaintext.class}"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
class << self
|
96
|
+
private
|
97
|
+
|
98
|
+
def validate_key(k, name)
|
99
|
+
unless k.is_a?(String) && k.encoding == Encoding::BINARY && k.bytesize == 16
|
100
|
+
raise ArgumentError, "#{name} must be a 16 octet binary string"
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
private
|
106
|
+
|
107
|
+
def encrypt_u64(plaintext)
|
108
|
+
if plaintext < 0
|
109
|
+
raise ArgumentError, "Cannot encrypt integers less than zero"
|
110
|
+
end
|
111
|
+
|
112
|
+
if plaintext >= 2**64
|
113
|
+
raise ArgumentError, "Cannot encrypt integers greater than 2^64 - 1"
|
114
|
+
end
|
115
|
+
|
116
|
+
_encrypt_u64(plaintext)
|
117
|
+
end
|
118
|
+
|
119
|
+
def encrypt_f64(plaintext)
|
120
|
+
if Float::MAX_EXP != 1024 || Float::MIN_EXP != -1021
|
121
|
+
# This is a pure sanity check, so...
|
122
|
+
#:nocov:
|
123
|
+
raise RuntimeError, "This platform does not conform to our expectations for floating-point representations. Out of an abundance of caution, we will not encrypt floats on this platform."
|
124
|
+
#:nocov:
|
125
|
+
end
|
126
|
+
|
127
|
+
if plaintext.nan?
|
128
|
+
raise ArgumentError, "Cannot ORE encrypt NaN"
|
129
|
+
end
|
130
|
+
|
131
|
+
_encrypt_f64(plaintext)
|
132
|
+
end
|
133
|
+
|
134
|
+
def encrypt_string(plaintext)
|
135
|
+
unless VALID_STRING_ENCODINGS.include?(plaintext.encoding)
|
136
|
+
raise ArgumentError, "Cannot encrypt non-UTF-8 string"
|
137
|
+
end
|
138
|
+
|
139
|
+
if !plaintext.valid_encoding?
|
140
|
+
raise ArgumentError, "Cannot encrypt invalid UTF-8 string"
|
141
|
+
end
|
142
|
+
|
143
|
+
_encrypt_string(plaintext)
|
144
|
+
end
|
145
|
+
|
146
|
+
def encrypt_bool(plaintext)
|
147
|
+
_encrypt_bool(plaintext)
|
148
|
+
end
|
149
|
+
|
150
|
+
def encrypt_range(plaintext)
|
151
|
+
min, max = plaintext.begin, plaintext.end
|
152
|
+
|
153
|
+
case [min.class, max.class]
|
154
|
+
# Integer ranges
|
155
|
+
when [Integer, Integer]
|
156
|
+
if max < min
|
157
|
+
raise ArgumentError, "Cannot encrypt a non-ascending range"
|
158
|
+
end
|
159
|
+
(encrypt_u64(min)..encrypt_u64(max))
|
160
|
+
when [Integer, NilClass]
|
161
|
+
(encrypt_u64(min)..encrypt_u64(2**64-1))
|
162
|
+
when [NilClass, Integer]
|
163
|
+
(encrypt_u64(0)..encrypt_u64(max))
|
164
|
+
|
165
|
+
# Float ranges
|
166
|
+
when [Float, Float]
|
167
|
+
if max < min
|
168
|
+
raise ArgumentError, "Cannot encrypt a non-ascending range"
|
169
|
+
end
|
170
|
+
(encrypt_f64(min)..encrypt_f64(max))
|
171
|
+
when [Float, NilClass]
|
172
|
+
(encrypt_f64(min)..encrypt_f64(Float::INFINITY))
|
173
|
+
when [NilClass, Float]
|
174
|
+
(encrypt_f64(-Float::INFINITY)..encrypt_f64(max))
|
175
|
+
|
176
|
+
# Date ranges
|
177
|
+
when [Date, Date]
|
178
|
+
encrypt_range(min.to_time..max.to_time)
|
179
|
+
when [Date, NilClass]
|
180
|
+
encrypt_range(min.to_time..)
|
181
|
+
when [NilClass, Date]
|
182
|
+
encrypt_range(..max.to_time)
|
183
|
+
|
184
|
+
# Time ranges
|
185
|
+
when [Time, Time]
|
186
|
+
(encrypt_time(min)..encrypt_time(max))
|
187
|
+
when [Time, NilClass]
|
188
|
+
(encrypt_time(min)..encrypt_u64(2**64-1))
|
189
|
+
when [NilClass, Time]
|
190
|
+
(encrypt_u64(0)..encrypt_time(max))
|
191
|
+
|
192
|
+
else
|
193
|
+
raise ArgumentError, "Cannot encrypt a range over #{min.class}..#{max.class}"
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
def encrypt_time(plaintext)
|
198
|
+
# Get the time in integer milliseconds, and then "shift" it so
|
199
|
+
# that times before the epoch are still positive numbers, just
|
200
|
+
# smaller than times after the epoch
|
201
|
+
encrypt_u64((plaintext.to_r * 1000).to_i + 2**63)
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|
data/lib/ore/version.rb
ADDED
data/lib/ore-rs.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
module ORE
|
2
|
+
end
|
3
|
+
|
4
|
+
begin
|
5
|
+
RUBY_VERSION =~ /(\d+\.\d+)/
|
6
|
+
require_relative "./#{$1}/ore_rs"
|
7
|
+
rescue LoadError
|
8
|
+
begin
|
9
|
+
require_relative "./ore_rs"
|
10
|
+
rescue LoadError
|
11
|
+
raise LoadError, "Could not load ore_rs binary library"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
require_relative "./ore/aes128"
|
data/ore-rs.gemspec
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
require_relative './lib/ore/version'
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = "ore-rs"
|
5
|
+
|
6
|
+
s.version = ORE::VERSION
|
7
|
+
s.date = Time.now.strftime("%Y-%m-%d")
|
8
|
+
|
9
|
+
s.platform = Gem::Platform::RUBY
|
10
|
+
|
11
|
+
s.summary = "Ruby bindings for the ore.rs Order-Revealing Encryption library"
|
12
|
+
|
13
|
+
s.authors = ["James Sadler", "Bennett Hardwick", "Drew Thomas"]
|
14
|
+
s.email = ["james@cipherstash.com", "bennett@cipherstash.com", "drew@cipherstash.com"]
|
15
|
+
s.homepage = "https://cipherstash.com/protect"
|
16
|
+
|
17
|
+
s.files = `git ls-files -z`.split("\0").reject { |f| f =~ /^(\.|G|spec|Rakefile)/ }
|
18
|
+
|
19
|
+
s.extensions = ["ext/ore_rs/extconf.rb"]
|
20
|
+
|
21
|
+
s.required_ruby_version = ">= 2.7.0"
|
22
|
+
|
23
|
+
s.metadata["homepage_uri"] = s.homepage
|
24
|
+
s.metadata["source_code_uri"] = "https://github.com/cipherstash/ruby-ore-rs"
|
25
|
+
s.metadata["changelog_uri"] = "https://github.com/cipherstash/ruby-ore-rs/releases"
|
26
|
+
s.metadata["bug_tracker_uri"] = "https://github.com/cipherstash/ruby-ore-rs/issues"
|
27
|
+
s.metadata["documentation_uri"] = "https://rubydoc.info/gems/ore-rs"
|
28
|
+
s.metadata["mailing_list_uri"] = "https://discuss.cipherstash.com"
|
29
|
+
|
30
|
+
s.add_runtime_dependency 'rb_sys', '~> 0.1'
|
31
|
+
|
32
|
+
s.add_development_dependency 'bundler'
|
33
|
+
s.add_development_dependency 'guard-rspec'
|
34
|
+
s.add_development_dependency 'rake', '~> 13.0'
|
35
|
+
s.add_development_dependency 'rake-compiler', '~> 1.2'
|
36
|
+
s.add_development_dependency 'rake-compiler-dock', '~> 1.2'
|
37
|
+
s.add_development_dependency 'rb-inotify', '~> 0.9'
|
38
|
+
s.add_development_dependency 'rb_sys', '~> 0.1'
|
39
|
+
s.add_development_dependency 'redcarpet'
|
40
|
+
s.add_development_dependency 'rspec'
|
41
|
+
s.add_development_dependency 'simplecov'
|
42
|
+
s.add_development_dependency 'yard'
|
43
|
+
end
|