confium 0.3.0 → 0.3.2
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 +4 -4
- data/CHANGELOG.md +57 -0
- data/Cargo.lock +106 -5
- data/Rakefile +22 -9
- data/confium.gemspec +28 -28
- data/ext/confium_native/Cargo.toml +1 -0
- data/ext/confium_native/extconf.rb +4 -4
- data/ext/confium_native/src/attributes.rs +1 -1
- data/ext/confium_native/src/audit.rs +1 -1
- data/ext/confium_native/src/composite.rs +1 -1
- data/ext/confium_native/src/deployment.rs +1 -1
- data/ext/confium_native/src/ers.rs +1 -1
- data/ext/confium_native/src/openpgp.rs +1 -1
- data/ext/confium_native/src/path.rs +1 -1
- data/ext/confium_native/src/pki.rs +1 -1
- data/ext/confium_native/src/tc.rs +2 -2
- data/ext/confium_native/src/transparency.rs +5 -3
- data/ext/confium_native/src/util.rs +5 -0
- data/lib/confium/audit.rb +5 -5
- data/lib/confium/cfm.rb +2 -1
- data/lib/confium/digest.rb +4 -2
- data/lib/confium/errors/coerce.rb +1 -3
- data/lib/confium/errors/crypto_error.rb +8 -6
- data/lib/confium/errors/index_error.rb +9 -7
- data/lib/confium/errors/not_found_error.rb +9 -7
- data/lib/confium/errors/parse_error.rb +9 -7
- data/lib/confium/errors/policy_violation_error.rb +9 -7
- data/lib/confium/errors/threshold_error.rb +9 -7
- data/lib/confium/errors/unresolved_signer_error.rb +8 -6
- data/lib/confium/errors/validation_error.rb +10 -8
- data/lib/confium/errors/verification_error.rb +9 -7
- data/lib/confium/errors.rb +1 -1
- data/lib/confium/ffi.rb +4 -4
- data/lib/confium/lib.rb +18 -19
- data/lib/confium/pki/certificate_builder.rb +3 -3
- data/lib/confium/pki/cms/signed_data_builder.rb +10 -10
- data/lib/confium/pki/cms.rb +1 -1
- data/lib/confium/pki/cnml.rb +8 -8
- data/lib/confium/pki.rb +1 -1
- data/lib/confium/policy.rb +13 -13
- data/lib/confium/secure_bytes.rb +91 -89
- data/lib/confium/tc/coordinator.rb +7 -6
- data/lib/confium/tc/session.rb +5 -3
- data/lib/confium/tc/session_stub.rb +2 -2
- data/lib/confium/tc/share_file.rb +13 -13
- data/lib/confium/tc.rb +2 -2
- data/lib/confium/version.rb +1 -1
- data/lib/confium.rb +32 -20
- metadata +8 -5
data/lib/confium/secure_bytes.rb
CHANGED
|
@@ -14,111 +14,113 @@
|
|
|
14
14
|
#
|
|
15
15
|
# After #clear, #bytes raises Confium::ClearedError.
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
17
|
+
module Confium
|
|
18
|
+
class SecureBytes
|
|
19
|
+
# Raised when #bytes is called after #clear.
|
|
20
|
+
class ClearedError < Confium::Error
|
|
21
|
+
def initialize(message = 'SecureBytes already cleared')
|
|
22
|
+
super(message, details: {})
|
|
23
|
+
end
|
|
22
24
|
end
|
|
23
|
-
end
|
|
24
25
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
26
|
+
# Create a SecureBytes wrapping a copy of the given String.
|
|
27
|
+
# The original String's contents are NOT modified; callers should
|
|
28
|
+
# zeroize the original separately if needed.
|
|
29
|
+
# @param raw [String] binary String (any encoding; bytes are copied)
|
|
30
|
+
# @return [Confium::SecureBytes]
|
|
31
|
+
def self.wrap(raw)
|
|
32
|
+
new(raw)
|
|
33
|
+
end
|
|
33
34
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
35
|
+
# @api private
|
|
36
|
+
def initialize(raw)
|
|
37
|
+
@buffer = raw.dup.force_encoding(Encoding::ASCII_8BIT)
|
|
38
|
+
@cleared = false
|
|
39
|
+
# Register finalizer to zeroize if the object is GC'd without
|
|
40
|
+
# an explicit #clear call.
|
|
41
|
+
ObjectSpace.define_finalizer(self, finalizer_proc)
|
|
42
|
+
end
|
|
42
43
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
44
|
+
# Non-destructive read of the wrapped bytes.
|
|
45
|
+
# @return [String] binary String (ASCII-8BIT encoding)
|
|
46
|
+
# @raise [ClearedError] if #clear was already called
|
|
47
|
+
def bytes
|
|
48
|
+
raise ClearedError if @cleared
|
|
48
49
|
|
|
49
|
-
|
|
50
|
-
|
|
50
|
+
@buffer.dup
|
|
51
|
+
end
|
|
51
52
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
53
|
+
# Destructive read: returns a copy, then zeroizes the original.
|
|
54
|
+
# @return [String] binary String
|
|
55
|
+
# @raise [ClearedError] if #clear was already called
|
|
56
|
+
def bytes!
|
|
57
|
+
raise ClearedError if @cleared
|
|
57
58
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
59
|
+
copy = @buffer.dup
|
|
60
|
+
clear
|
|
61
|
+
copy
|
|
62
|
+
end
|
|
62
63
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
64
|
+
# Number of bytes. Returns 0 after #clear.
|
|
65
|
+
# @return [Integer]
|
|
66
|
+
def length
|
|
67
|
+
@cleared ? 0 : @buffer.bytesize
|
|
68
|
+
end
|
|
68
69
|
|
|
69
|
-
|
|
70
|
+
alias size length
|
|
70
71
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
72
|
+
# Whether the buffer has been cleared.
|
|
73
|
+
# @return [Boolean]
|
|
74
|
+
def cleared?
|
|
75
|
+
@cleared
|
|
76
|
+
end
|
|
76
77
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
78
|
+
# Zeroize the buffer immediately. Idempotent.
|
|
79
|
+
# @return [self]
|
|
80
|
+
def clear
|
|
81
|
+
return self if @cleared
|
|
81
82
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
83
|
+
# Overwrite every byte with 0x00 in place.
|
|
84
|
+
@buffer.replace("\x00" * @buffer.bytesize)
|
|
85
|
+
@buffer = nil
|
|
86
|
+
@cleared = true
|
|
87
|
+
self
|
|
88
|
+
end
|
|
88
89
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
90
|
+
# String representation for debugging. Does NOT expose the raw bytes.
|
|
91
|
+
# @return [String]
|
|
92
|
+
def inspect
|
|
93
|
+
if @cleared
|
|
94
|
+
"#<Confium::SecureBytes:0x#{object_id.to_s(16)} CLEARED>"
|
|
95
|
+
else
|
|
96
|
+
"#<Confium::SecureBytes:0x#{object_id.to_s(16)} #{length} bytes>"
|
|
97
|
+
end
|
|
96
98
|
end
|
|
97
|
-
end
|
|
98
99
|
|
|
99
|
-
|
|
100
|
+
private
|
|
100
101
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
102
|
+
# Finalizer proc that zeroizes the buffer if GC collects this
|
|
103
|
+
# object without an explicit #clear. Uses object_id to find the
|
|
104
|
+
# buffer — but since the buffer is an instance variable that may
|
|
105
|
+
# already be collected, this is a best-effort path. Explicit #clear
|
|
106
|
+
# is the recommended path.
|
|
107
|
+
# @return [Proc]
|
|
108
|
+
def finalizer_proc
|
|
109
|
+
method(:finalize)
|
|
110
|
+
end
|
|
110
111
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
112
|
+
# Called by the GC finalizer.
|
|
113
|
+
def finalize(_id)
|
|
114
|
+
# Best-effort: the buffer may already be collected by the time
|
|
115
|
+
# the finalizer runs. If @buffer still exists, zeroize it.
|
|
116
|
+
# This is a closure over the instance — MRI guarantees the
|
|
117
|
+
# finalizer runs after the object is unreachable but before
|
|
118
|
+
# the buffer's memory is reused.
|
|
119
|
+
return if @cleared
|
|
120
|
+
|
|
121
|
+
@buffer&.replace("\x00" * @buffer.bytesize)
|
|
122
|
+
@buffer = nil
|
|
123
|
+
@cleared = true
|
|
124
|
+
end
|
|
123
125
|
end
|
|
124
126
|
end
|
|
@@ -25,7 +25,7 @@ module Confium
|
|
|
25
25
|
@sessions = {}
|
|
26
26
|
end
|
|
27
27
|
|
|
28
|
-
def create_session(message:, threshold:, unlock_window:
|
|
28
|
+
def create_session(message:, threshold:, unlock_window: 14_400)
|
|
29
29
|
session_id = "session-#{@sessions.length + 1}"
|
|
30
30
|
@sessions[session_id] = {
|
|
31
31
|
message: message,
|
|
@@ -33,7 +33,7 @@ module Confium
|
|
|
33
33
|
unlock_window: unlock_window,
|
|
34
34
|
state: :pending,
|
|
35
35
|
commitments: [],
|
|
36
|
-
shares: []
|
|
36
|
+
shares: []
|
|
37
37
|
}
|
|
38
38
|
session_id
|
|
39
39
|
end
|
|
@@ -45,9 +45,9 @@ module Confium
|
|
|
45
45
|
def submit_commitment(session_id, signer_id, commitment_bytes)
|
|
46
46
|
session = @sessions[session_id] or raise "Unknown session: #{session_id}"
|
|
47
47
|
session[:commitments] << { signer_id: signer_id, bytes: commitment_bytes }
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
48
|
+
return unless session[:commitments].length >= session[:threshold]
|
|
49
|
+
|
|
50
|
+
session[:state] = :commitments_collected
|
|
51
51
|
end
|
|
52
52
|
|
|
53
53
|
def submit_share(session_id, signer_id, share_bytes)
|
|
@@ -57,7 +57,8 @@ module Confium
|
|
|
57
57
|
|
|
58
58
|
def aggregate(session_id)
|
|
59
59
|
session = @sessions[session_id] or raise "Unknown session: #{session_id}"
|
|
60
|
-
raise
|
|
60
|
+
raise 'Threshold not met' if session[:shares].length < session[:threshold]
|
|
61
|
+
|
|
61
62
|
session[:state] = :completed
|
|
62
63
|
# In real implementation, calls FFI to aggregate shares
|
|
63
64
|
session[:shares].map { |s| s[:bytes] }.join
|
data/lib/confium/tc/session.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
3
|
+
require 'confium/lib'
|
|
4
4
|
|
|
5
5
|
# Confium::TC::Session wraps a threshold cryptography session.
|
|
6
6
|
#
|
|
@@ -32,7 +32,8 @@ module Confium
|
|
|
32
32
|
end
|
|
33
33
|
|
|
34
34
|
def set_local_share(share_bytes)
|
|
35
|
-
raise ArgumentError,
|
|
35
|
+
raise ArgumentError, 'share must be a String' unless share_bytes.is_a?(String)
|
|
36
|
+
|
|
36
37
|
@local_share = share_bytes
|
|
37
38
|
end
|
|
38
39
|
|
|
@@ -41,7 +42,8 @@ module Confium
|
|
|
41
42
|
end
|
|
42
43
|
|
|
43
44
|
def result
|
|
44
|
-
raise
|
|
45
|
+
raise 'Session not complete' unless complete?
|
|
46
|
+
|
|
45
47
|
@result
|
|
46
48
|
end
|
|
47
49
|
end
|
|
@@ -31,12 +31,12 @@ module Confium
|
|
|
31
31
|
# call confium_tc::session::Session::round_step.
|
|
32
32
|
def round_step(_incoming_messages)
|
|
33
33
|
@round += 1
|
|
34
|
-
@complete = @round >= 3
|
|
34
|
+
@complete = @round >= 3 # FROST is 3 rounds
|
|
35
35
|
{ outgoing: [], complete: @complete }
|
|
36
36
|
end
|
|
37
37
|
|
|
38
38
|
def result
|
|
39
|
-
nil
|
|
39
|
+
nil # Real implementation returns the signature/secret bytes.
|
|
40
40
|
end
|
|
41
41
|
end
|
|
42
42
|
end
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
4
|
-
require
|
|
3
|
+
require 'json'
|
|
4
|
+
require 'fileutils'
|
|
5
5
|
|
|
6
6
|
module Confium
|
|
7
7
|
module TC
|
|
@@ -46,11 +46,11 @@ module Confium
|
|
|
46
46
|
def self.from_json(json)
|
|
47
47
|
d = JSON.parse(json)
|
|
48
48
|
new(
|
|
49
|
-
scheme: d.fetch(
|
|
50
|
-
threshold: d.fetch(
|
|
51
|
-
party_count: d.fetch(
|
|
52
|
-
public_key: [d.fetch(
|
|
53
|
-
shares: d.fetch(
|
|
49
|
+
scheme: d.fetch('scheme'),
|
|
50
|
+
threshold: d.fetch('threshold'),
|
|
51
|
+
party_count: d.fetch('party_count'),
|
|
52
|
+
public_key: [d.fetch('public_key')].pack('H*'),
|
|
53
|
+
shares: d.fetch('shares').map { |h| [h].pack('H*') }
|
|
54
54
|
)
|
|
55
55
|
end
|
|
56
56
|
|
|
@@ -67,8 +67,8 @@ module Confium
|
|
|
67
67
|
scheme: scheme,
|
|
68
68
|
threshold: threshold,
|
|
69
69
|
party_count: party_count,
|
|
70
|
-
public_key: public_key.unpack1(
|
|
71
|
-
shares: shares.map { |s| s.unpack1(
|
|
70
|
+
public_key: public_key.unpack1('H*'),
|
|
71
|
+
shares: shares.map { |s| s.unpack1('H*') }
|
|
72
72
|
)
|
|
73
73
|
end
|
|
74
74
|
|
|
@@ -76,10 +76,10 @@ module Confium
|
|
|
76
76
|
def self.from_keygen(scheme_name, keygen_result)
|
|
77
77
|
new(
|
|
78
78
|
scheme: scheme_name,
|
|
79
|
-
threshold: nil,
|
|
80
|
-
party_count: keygen_result[
|
|
81
|
-
public_key: keygen_result[
|
|
82
|
-
shares: keygen_result[
|
|
79
|
+
threshold: nil, # not carried by the keygen Hash; caller knows
|
|
80
|
+
party_count: keygen_result['shares'].length,
|
|
81
|
+
public_key: keygen_result['public_key'],
|
|
82
|
+
shares: keygen_result['shares']
|
|
83
83
|
)
|
|
84
84
|
end
|
|
85
85
|
end
|
data/lib/confium/tc.rb
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
# for the full interface specification.
|
|
12
12
|
module Confium
|
|
13
13
|
module TC
|
|
14
|
-
autoload :Session,
|
|
15
|
-
autoload :Coordinator,
|
|
14
|
+
autoload :Session, 'confium/tc/session'
|
|
15
|
+
autoload :Coordinator, 'confium/tc/coordinator'
|
|
16
16
|
end
|
|
17
17
|
end
|
data/lib/confium/version.rb
CHANGED
data/lib/confium.rb
CHANGED
|
@@ -9,51 +9,63 @@
|
|
|
9
9
|
# Pure-Ruby companions (the error hierarchy, Enumerable mixins, etc.)
|
|
10
10
|
# are loaded lazily via autoload — see lib/confium/<name>.rb.
|
|
11
11
|
|
|
12
|
-
require_relative
|
|
12
|
+
require_relative 'confium/version'
|
|
13
13
|
|
|
14
14
|
begin
|
|
15
|
-
|
|
15
|
+
# Pre-built platform gems ship one extension per C-ABI window
|
|
16
|
+
# (Ruby 3.2 broke the 3.1 ABI — object shapes — and rb-sys
|
|
17
|
+
# references the VM pointer libruby stopped exporting in 3.3, so
|
|
18
|
+
# 3.1 and 3.2 get exact-minor builds while 3.3 covers 3.3+).
|
|
19
|
+
# Source builds install the extension flat, without a version
|
|
20
|
+
# directory.
|
|
21
|
+
major, minor = RUBY_VERSION.split('.').first(2).map(&:to_i)
|
|
22
|
+
window = major > 3 || minor >= 3 ? '3.3' : "#{major}.#{minor}"
|
|
23
|
+
begin
|
|
24
|
+
require_relative "confium_native/#{window}/confium_native"
|
|
25
|
+
rescue LoadError
|
|
26
|
+
require_relative 'confium_native/confium_native'
|
|
27
|
+
end
|
|
16
28
|
rescue LoadError => e
|
|
17
|
-
warn
|
|
29
|
+
warn 'confium: native extension not built — run `bundle exec rake compile`'
|
|
18
30
|
raise e
|
|
19
31
|
end
|
|
20
32
|
|
|
21
33
|
# Register autoloads on the native-defined PKI::CMS module so Ruby
|
|
22
34
|
# companions like SignedDataBuilder load on first reference. Eager-
|
|
23
35
|
# required because the module already exists at this point.
|
|
24
|
-
require_relative
|
|
36
|
+
require_relative 'confium/pki/cms'
|
|
25
37
|
|
|
26
38
|
# The native extension defines Confium::OpenPGP with _native_armor /
|
|
27
39
|
# _native_dearmor. This file adds the idiomatic Ruby wrappers with
|
|
28
40
|
# default args. Eager-required for the same reason as PKI::CMS.
|
|
29
|
-
require_relative
|
|
41
|
+
require_relative 'confium/openpgp'
|
|
30
42
|
|
|
31
43
|
module Confium
|
|
32
44
|
# Error hierarchy autoloads. Each subclass lives in its own file so
|
|
33
45
|
# callers can `autoload :FooError, "confium/errors/foo"` and avoid
|
|
34
46
|
# loading the whole hierarchy if they only rescue one type.
|
|
35
|
-
autoload :Error,
|
|
36
|
-
autoload :ParseError,
|
|
37
|
-
autoload :ValidationError,
|
|
38
|
-
autoload :VerificationError,
|
|
39
|
-
autoload :ThresholdError,
|
|
40
|
-
autoload :CryptoError,
|
|
41
|
-
autoload :NotFoundError,
|
|
42
|
-
autoload :IndexError,
|
|
43
|
-
autoload :UnresolvedSignerError,
|
|
44
|
-
autoload :PolicyViolationError,
|
|
45
|
-
autoload :SecureBytes,
|
|
46
|
-
autoload :Policy,
|
|
47
|
-
autoload :PKI,
|
|
47
|
+
autoload :Error, 'confium/errors'
|
|
48
|
+
autoload :ParseError, 'confium/errors/parse_error'
|
|
49
|
+
autoload :ValidationError, 'confium/errors/validation_error'
|
|
50
|
+
autoload :VerificationError, 'confium/errors/verification_error'
|
|
51
|
+
autoload :ThresholdError, 'confium/errors/threshold_error'
|
|
52
|
+
autoload :CryptoError, 'confium/errors/crypto_error'
|
|
53
|
+
autoload :NotFoundError, 'confium/errors/not_found_error'
|
|
54
|
+
autoload :IndexError, 'confium/errors/index_error'
|
|
55
|
+
autoload :UnresolvedSignerError, 'confium/errors/unresolved_signer_error'
|
|
56
|
+
autoload :PolicyViolationError, 'confium/errors/policy_violation_error'
|
|
57
|
+
autoload :SecureBytes, 'confium/secure_bytes'
|
|
58
|
+
autoload :Policy, 'confium/policy'
|
|
59
|
+
autoload :PKI, 'confium/pki'
|
|
48
60
|
end
|
|
49
61
|
|
|
50
62
|
# Eager-load the Audit Ruby companion. The native extension registers
|
|
51
63
|
# `Confium::Audit` as a Ruby module with the `record`/`sink=`/`sink`
|
|
52
64
|
# methods; the companion file defines the Sink class hierarchy on top
|
|
53
65
|
# of that module.
|
|
54
|
-
require_relative
|
|
66
|
+
require_relative 'confium/audit'
|
|
55
67
|
|
|
56
68
|
# Eager-load the TC ShareFile Ruby companion. The native extension
|
|
57
69
|
# defines `Confium::TC` as a Ruby module; this file adds the
|
|
58
70
|
# `ShareFile` class for filesystem-backed share persistence.
|
|
59
|
-
require_relative
|
|
71
|
+
require_relative 'confium/tc/share_file'
|
metadata
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: confium
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.3.
|
|
4
|
+
version: 0.3.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose Open
|
|
8
|
+
autorequire:
|
|
8
9
|
bindir: bin
|
|
9
10
|
cert_chain: []
|
|
10
|
-
date:
|
|
11
|
+
date: 2026-08-22 00:00:00.000000000 Z
|
|
11
12
|
dependencies:
|
|
12
13
|
- !ruby/object:Gem::Dependency
|
|
13
14
|
name: rb_sys
|
|
@@ -43,14 +44,14 @@ dependencies:
|
|
|
43
44
|
requirements:
|
|
44
45
|
- - "~>"
|
|
45
46
|
- !ruby/object:Gem::Version
|
|
46
|
-
version: 1.
|
|
47
|
+
version: 1.3.0
|
|
47
48
|
type: :development
|
|
48
49
|
prerelease: false
|
|
49
50
|
version_requirements: !ruby/object:Gem::Requirement
|
|
50
51
|
requirements:
|
|
51
52
|
- - "~>"
|
|
52
53
|
- !ruby/object:Gem::Version
|
|
53
|
-
version: 1.
|
|
54
|
+
version: 1.3.0
|
|
54
55
|
- !ruby/object:Gem::Dependency
|
|
55
56
|
name: rake-compiler-dock
|
|
56
57
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -182,6 +183,7 @@ metadata:
|
|
|
182
183
|
homepage_uri: https://www.confium.org
|
|
183
184
|
source_code_uri: https://github.com/confium/confium-ruby
|
|
184
185
|
rubygems_mfa_required: 'true'
|
|
186
|
+
post_install_message:
|
|
185
187
|
rdoc_options: []
|
|
186
188
|
require_paths:
|
|
187
189
|
- lib
|
|
@@ -196,7 +198,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
196
198
|
- !ruby/object:Gem::Version
|
|
197
199
|
version: '0'
|
|
198
200
|
requirements: []
|
|
199
|
-
rubygems_version:
|
|
201
|
+
rubygems_version: 3.5.22
|
|
202
|
+
signing_key:
|
|
200
203
|
specification_version: 4
|
|
201
204
|
summary: Ruby bindings for the Confium multi-stakeholder threshold cryptography framework.
|
|
202
205
|
test_files: []
|