Class: RingSig::Key
- Inherits:
-
Object
- Object
- RingSig::Key
- Defined in:
- lib/ring_sig/key.rb
Overview
Instances of this class represent an ECDSA key.
Instance Attribute Summary collapse
- #group ⇒ ECDSA::Group readonly
- #hash_algorithm ⇒ #digest readonly
- #private_key ⇒ Integer readonly
- #public_key ⇒ ECDSA::Point readonly
Instance Method Summary collapse
-
#drop_private_key ⇒ Key
Returns self if this key has no private key.
-
#initialize(private_key: nil, public_key: nil, group: ECDSA::Group::Secp256k1, hash_algorithm: OpenSSL::Digest::SHA256) ⇒ Key
constructor
Creates a new instance of Key.
-
#key_image ⇒ ECDSA::Point
The key image.
-
#sign(message, foreign_keys) ⇒ Array(Signature, Array<Key>)
Signs a message with this key’s private_key and a set of public foreign keys.
Constructor Details
#initialize(private_key: nil, public_key: nil, group: ECDSA::Group::Secp256k1, hash_algorithm: OpenSSL::Digest::SHA256) ⇒ Key
Creates a new instance of RingSig::Key. Must provide either a private_key or a public_key, but not both.
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
# File 'lib/ring_sig/key.rb', line 24 def initialize( private_key: nil, public_key: nil, group: ECDSA::Group::Secp256k1, hash_algorithm: OpenSSL::Digest::SHA256) if private_key && public_key raise ArgumentError, "Must not provide both private_key and public_key" elsif private_key raise ArgumentError, "Private key is not an integer" unless private_key.is_a?(Integer) raise ArgumentError, "Private key is too small" if private_key < 1 raise ArgumentError, "Private key is too large" if private_key >= group.order @private_key = private_key @public_key = group.generator.multiply_by_scalar(private_key) elsif public_key raise ArgumentError, "Public key is not an ECDSA::Point" unless public_key.is_a?(ECDSA::Point) raise ArgumentError, "Public key is not on the group's curve" unless group.include?(public_key) @public_key = public_key else raise ArgumentError, "Must provide either private_key or public_key" end @group = group @hash_algorithm = hash_algorithm @hasher = RingSig::Hasher.new(group, hash_algorithm) end |
Instance Attribute Details
#group ⇒ ECDSA::Group (readonly)
12 13 14 |
# File 'lib/ring_sig/key.rb', line 12 def group @group end |
#hash_algorithm ⇒ #digest (readonly)
15 16 17 |
# File 'lib/ring_sig/key.rb', line 15 def hash_algorithm @hash_algorithm end |
#private_key ⇒ Integer (readonly)
6 7 8 |
# File 'lib/ring_sig/key.rb', line 6 def private_key @private_key end |
#public_key ⇒ ECDSA::Point (readonly)
9 10 11 |
# File 'lib/ring_sig/key.rb', line 9 def public_key @public_key end |
Instance Method Details
#drop_private_key ⇒ Key
Returns self if this key has no private key. Otherwise, returns a new key with only the public_key component.
92 93 94 95 |
# File 'lib/ring_sig/key.rb', line 92 def drop_private_key return self unless private_key Key.new(public_key: public_key, group: group, hash_algorithm: hash_algorithm) end |
#key_image ⇒ ECDSA::Point
Returns the key image.
83 84 85 86 |
# File 'lib/ring_sig/key.rb', line 83 def key_image raise ArgumentError "Cannot compute key image without the private key" unless private_key @key_image ||= @hasher.hash_point(@public_key) * @private_key end |
#sign(message, foreign_keys) ⇒ Array(Signature, Array<Key>)
Signs a message with this key’s private_key and a set of public foreign keys. The resulting signature can be verified against the ordered set of all public keys used for creating this signature. The signature will also contain a key_image which will be the same for all messages signed with this key.
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/ring_sig/key.rb', line 61 def sign(, foreign_keys) raise ArgumentError "Cannot sign without a private key" unless private_key raise ArgumentError "Foreign keys must all have to the same group" unless foreign_keys.all?{|e| e.group == group} raise ArgumentError "Foreign keys must all have to the same hash_algorithm" unless foreign_keys.all?{|e| e.hash_algorithm == hash_algorithm} = @hasher.hash_string() seed = @hasher.hash_array([private_key, ]) foreign_keys = foreign_keys.map(&:drop_private_key) all_keys = @hasher.shuffle([self] + foreign_keys, seed) q_array, w_array = generate_q_w(all_keys, seed) ll_array, rr_array = generate_ll_rr(all_keys, q_array, w_array) challenge = @hasher.hash_array([] + ll_array + rr_array) c_array, r_array = generate_c_r(all_keys, q_array, w_array, challenge) public_keys = all_keys.map(&:drop_private_key) [RingSig::Signature.new(key_image, c_array, r_array, group: group, hash_algorithm: @hasher.algorithm), public_keys] end |