sharing 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b091eefc1c0e4656e732cfdbc983177df829e0c646467227871bf2a3dfc18203
4
- data.tar.gz: 493c97755883f09df9fd19b9e9f9dcb09f4a15756cd22401bce780e4b574123c
3
+ metadata.gz: 719563755ad21ee302ca5c4cdf7dc99d5392f03f5a42af56a38a9199a76e5d31
4
+ data.tar.gz: f58c948f6c1c26cc2cc0f7f6e0c318a2c46d2c219952757bf43d092328f5b6ec
5
5
  SHA512:
6
- metadata.gz: 6405b3a080f2a669b1f0882d9baec0e29c7ffaa93cafb5738a1636fdf58f596129c7a8436470dfbb4fd059e78b15b9b060a557bfb789e1316dbf1605b031545b
7
- data.tar.gz: 5a8096e9f83b122550d62cd97417b928bd37d64a5902c857a7d7c7f515ddb97264ab1b87cbde0590e9e7bdcda3acdb4c95a75cdaab0fb0bb9bad120f91373e6a
6
+ metadata.gz: 678102cac63e5994565e6b7628e7ebd5865b696d996684a4ccfb1c073d8f028270989fc7f8771f0010df25529aaf97cb8265133b61e22b3188d11654c37ee851
7
+ data.tar.gz: a7903a1cdb18224fba5ceca2443c8856fca3368534c839bc5daf50a09dcbfdd8bb953c3d715534ec21d5f16b662d8f8d9e2a3162461b90a1763607c932447914
data/.codecov.yml ADDED
@@ -0,0 +1,6 @@
1
+ coverage:
2
+ status:
3
+ project:
4
+ default:
5
+ target: 99% # the required coverage value
6
+ threshold: 1% # the leniency in hitting the target
data/.rubocop.yml CHANGED
@@ -1,6 +1,9 @@
1
1
  AllCops:
2
2
  NewCops: enable
3
3
  TargetRubyVersion: 2.6
4
+ Exclude:
5
+ - 'lab/**/*'
6
+ - 'vendor/**/*'
4
7
 
5
8
  Style/StringLiterals:
6
9
  Enabled: true
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ ## [0.3.0] - 2022-05-23
2
+
3
+ - Add division to Shamir's secret sharing implementation.
4
+
1
5
  ## [0.2.0] - 2022-03-25
2
6
 
3
7
  - Add multiplication to Shamir's secret sharing implementation and overall improvements.
data/Gemfile CHANGED
@@ -19,8 +19,6 @@ gem "rubocop-rake", "~> 0.6"
19
19
 
20
20
  gem "minitest-reporters", "~> 1.5"
21
21
 
22
- gem "simplecov", "~>0.21", require: false
22
+ gem "codecov", require: false, group: :test
23
23
 
24
24
  gem "simplecov-console", "~>0.9", require: false
25
-
26
- gem "codecov", require: false, group: "test"
data/Gemfile.lock CHANGED
@@ -79,7 +79,6 @@ DEPENDENCIES
79
79
  rubocop-minitest (~> 0.17.2)
80
80
  rubocop-rake (~> 0.6)
81
81
  sharing!
82
- simplecov (~> 0.21)
83
82
  simplecov-console (~> 0.9)
84
83
 
85
84
  RUBY VERSION
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Sharing
2
2
 
3
- ![GitHub Workflow Status](https://img.shields.io/github/workflow/status/davidwilliam/sharing/Ruby)
3
+ ![GitHub Workflow Status](https://github.com/davidwilliam/sharing/actions/workflows/main.yml/badge.svg) [![Ruby Style Guide](https://img.shields.io/badge/code_style-rubocop-brightgreen.svg)](https://github.com/rubocop/rubocop) ![GitHub](https://img.shields.io/github/license/davidwilliam/sharing) ![Gem](https://img.shields.io/gem/v/sharing) ![GitHub release (latest by date)](https://img.shields.io/github/v/release/davidwilliam/sharing)
4
4
 
5
5
  Sharing is a Ruby gem with implmementations of secret sharing schemes with homomorphic properties. Although secret sharing schemes and multiparty computation protocols are distinct notions, multiparty computation protocols are typically enabled by secret sharing schemes. In this setting, security comes from the use of multiple parties. If they collude, all security is lost, but satisfactory levels of security can be established by trusting a subset of them will not to collude. In many settings where corrupting security requires corrupting all the parties, and considering you are one of the computing parties, security is guaranteed if you are one of the parties.
6
6
 
@@ -264,6 +264,90 @@ reconstructed_secret = sss.reconstruct_secret(selected_shares)
264
264
 
265
265
  Everything else works the sabe as before except the fact that only `3` shares are required to reconstruct the secret.
266
266
 
267
+ ### Division
268
+
269
+ Here we simulate a division algorithm computed over the shares. Consider the following configuration:
270
+
271
+ ```ruby
272
+ {:lambda_=>16, :total_shares=>6, :threshold=>3}
273
+ sss = Sharing::Polynomial::Shamir::V1.new(params)
274
+ ```
275
+
276
+ and the rational numbers
277
+
278
+ ```ruby
279
+ rat1 = Rational(2, 3)
280
+ rat2 = Rational(-5, 7)
281
+ ```
282
+
283
+ We compute their Hensel code so we define our secrets:
284
+
285
+ ```ruby
286
+ secret1 = HenselCode::TFPE.new(sss.p, 1, rat1).hensel_code
287
+ # => 40896
288
+ secret2 = HenselCode::TFPE.new(sss.p, 1, rat2).hensel_code
289
+ # => 52579
290
+ ```
291
+
292
+ We then comute the shares for each secret:
293
+
294
+ ```ruby
295
+ shares1 = sss.create_shares(secret1)
296
+ # => [[1, 22792], [2, 38518], [3, 26731], [4, 48774], [5, 43304], [6, 10321]]
297
+ shares2 = sss.create_shares(secret2)
298
+ # => [[1, 37982], [2, 294], [3, 858], [4, 39674], [5, 55399], [6, 48033]]
299
+ ```
300
+
301
+ We select a subset of the shares of eacg secret based on the threshold:
302
+
303
+ ```ruby
304
+ selected_shares1 = shares1.sample(sss.threshold)
305
+ # => [[1, 22792], [5, 43304], [6, 10321]]
306
+ selected_shares2 = shares2.sample(sss.threshold)
307
+ # => [[6, 48033], [2, 294], [1, 37982]]
308
+ ```
309
+
310
+ A party that is not one of the selected parties (a trusted party for instance) generates three random values that will later used:
311
+
312
+ ```ruby
313
+ r1, r2, r3 = Sharing::Polynomial::Shamir::V1.generate_division_masking(sss.p)
314
+ => [23078, 18925, 18812]
315
+ ```
316
+
317
+ Each party multiply their shares of the first operand by `r1` and the shares of the second operand by `r2`. For convenience (given our simulation), this step is here done all at once as follows:
318
+
319
+ ```ruby
320
+ cs, ds = Sharing::Polynomial::Shamir::V1.compute_numerator_denominator(selected_shares1, selected_shares2, r1, r2, sss.p)
321
+ => [[[1, 38894], [5, 30899], [6, 54512]], [[6, 43951], [2, 43080], [1, 53419]]]
322
+ ```
323
+
324
+ `cs` denote the shares representing the numerator of the division and `ds` represent the shares of the denominator of the division, as in `c/d`.
325
+
326
+ Finally, in the reconstruction step, `c` and `d` are reconstructed and `r3` is used to invert the multiplication by `r1` and `r2` that was previously computed by the parties. With the correct values recovered, we compute the Hensel decoding and then we obtain the final result without revealing what the numerator and denominator were. For convenience, we execute these steps as follows:
327
+
328
+ ```ruby
329
+ sss.reconstruct_division(cs, ds, r3)
330
+ # => (-14/15)
331
+ ```
332
+
333
+ We can also use only a subset of the shares:
334
+
335
+ ```ruby
336
+ selected_cs = cs.sample(sss.threshold)
337
+ => [[5, 30899], [1, 38894], [6, 54512]]
338
+ selected_ds = ds.sample(sss.threshold)
339
+ # => [[2, 43080], [1, 53419], [6, 43951]]
340
+ sss.reconstruct_division(selected_cs, selected_ds, r3)
341
+ => (-14/15)
342
+ ```
343
+
344
+ And we can check that
345
+
346
+ ```ruby
347
+ rat1 / rat2
348
+ # => (-14/15)
349
+ ```
350
+
267
351
  ## Asmuth-Bloom V2
268
352
 
269
353
  The Asmuth-Bloom V2 was proposed by Ersoy et al. in in [Homomorphic extensions of CRT-based secret sharing](https://www.sciencedirect.com/science/article/pii/S0166218X20303012)). The reference is a CRT-based secret sharing scheme introduced by Asmuth-Bloom in [A modular approach to key safeguarding](https://ieeexplore.ieee.org/abstract/document/1056651).
@@ -326,6 +410,19 @@ crtss.reconstruct_secret(selected_shares1_add_shares2_add_shares1_mul_shares2)
326
410
 
327
411
  and we can check that 5 + 8 = 13, 5 * 8 = 40, and 13 + 40 = 53.
328
412
 
413
+ ## Author
414
+
415
+ David William Silva
416
+
417
+ ## Contributors
418
+
419
+ David William Silva (Algemetric)
420
+ Marcio Junior (Algemetric)
421
+
422
+ ## Acknowledgements
423
+
424
+ Luke Harmon (Algemetric) and Gaetan Delavignette (Algemetric) have been instrumental by providing/conducting mathematical analyses, tests, and overall recommendations for improving the gem.
425
+
329
426
  ## Development
330
427
 
331
428
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -338,4 +435,4 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/davidw
338
435
 
339
436
  ## License
340
437
 
341
- The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
438
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
@@ -69,6 +69,18 @@ module Sharing
69
69
  (1..total_shares).map.with_index { |x, i| [i + 1, f(x, secret, random_coefficients) % prime] }
70
70
  end
71
71
 
72
+ def self.generate_division_masking(prime)
73
+ r1, r2 = random_distinct_numbers("integer", 2, prime.bit_length - 1)
74
+ r3 = (r2 * mod_inverse(r1, prime)) % prime
75
+ [r1, r2, r3]
76
+ end
77
+
78
+ def self.compute_numerator_denominator(shares1, shares2, r1_, r2_, prime)
79
+ cs = shares1.map { |i, share| [i, (share * r1_) % prime] }
80
+ ds = shares2.map { |i, share| [i, (share * r2_) % prime] }
81
+ [cs, ds]
82
+ end
83
+
72
84
  def initialize(params = {})
73
85
  @lambda_ = params[:lambda_]
74
86
  @total_shares = params[:total_shares]
@@ -93,6 +105,12 @@ module Sharing
93
105
  encode_to_integer(reconstructed_secret)
94
106
  end
95
107
 
108
+ def reconstruct_division(cs_, ds_, r3_)
109
+ c, d = [cs_, ds_].map { |shares| reconstruct_secret(shares) }
110
+ c_d_encoded = (c * mod_inverse(d, p) * r3_) % p
111
+ HenselCode::TruncatedFinitePadicExpansion.new(p, 1, c_d_encoded).to_r
112
+ end
113
+
96
114
  private
97
115
 
98
116
  def generate_prime
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Sharing
4
- VERSION = "0.2.0"
4
+ VERSION = "0.3.0"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sharing
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - David William Silva
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-03-25 00:00:00.000000000 Z
11
+ date: 2022-05-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: hensel_code
@@ -45,6 +45,7 @@ executables: []
45
45
  extensions: []
46
46
  extra_rdoc_files: []
47
47
  files:
48
+ - ".codecov.yml"
48
49
  - ".rubocop.yml"
49
50
  - CHANGELOG.md
50
51
  - Gemfile