Class: RingSig::PrivateKey
- Inherits:
-
Object
- Object
- RingSig::PrivateKey
- Defined in:
- lib/ring_sig/private_key.rb
Overview
Instances of this class represent a private ECDSA key.
Instance Attribute Summary collapse
- #group ⇒ ECDSA::Group readonly
- #hash_algorithm ⇒ #digest readonly
- #public_key ⇒ PublicKey readonly
-
#value ⇒ Integer
readonly
The integer value of this private key.
Class Method Summary collapse
-
.from_hex(hex_string, opts = {}) ⇒ PrivateKey
Creates a new instance of PrivateKey from a hex string.
-
.from_octet(octet_string, opts = {}) ⇒ PrivateKey
Creates a new instance of PrivateKey from an octet string.
Instance Method Summary collapse
-
#==(other) ⇒ Boolean
True if the private keys are equal.
-
#initialize(value, opts = {}) ⇒ PrivateKey
constructor
Creates a new instance of PrivateKey.
-
#key_image ⇒ ECDSA::Point
The key image.
-
#point ⇒ ECDSA::Point
The public key's point.
-
#sign(message, foreign_keys) ⇒ Array(Signature, Array<PublicKey>)
Signs a message with this key's private key and a set of foreign public keys.
-
#to_hex ⇒ String
Encodes this private key into an octet string.
-
#to_octet ⇒ String
Encodes this public key into a hex string.
Constructor Details
#initialize(value, opts = {}) ⇒ PrivateKey
Creates a new instance of RingSig::PrivateKey.
26 27 28 29 30 31 32 33 34 35 36 37 38 |
# File 'lib/ring_sig/private_key.rb', line 26 def initialize(value, opts = {}) @group = opts.delete(:group) { RingSig.default_group } @hash_algorithm = opts.delete(:hash_algorithm) { RingSig.default_hash_algorithm } raise ArgumentError, "Unknown opts: #{opts.keys.join(', ')}" unless opts.empty? raise ArgumentError, "Value is not an integer" unless value.is_a?(Integer) raise ArgumentError, "Value is too small" if value < 1 raise ArgumentError, "Value is too large" if value >= group.order @value = value @public_key = PublicKey.new(group.generator.multiply_by_scalar(value), group: group) @hasher = Hasher.new(group: group, hash_algorithm: hash_algorithm) end |
Instance Attribute Details
#group ⇒ ECDSA::Group (readonly)
15 16 17 |
# File 'lib/ring_sig/private_key.rb', line 15 def group @group end |
#hash_algorithm ⇒ #digest (readonly)
18 19 20 |
# File 'lib/ring_sig/private_key.rb', line 18 def hash_algorithm @hash_algorithm end |
#public_key ⇒ PublicKey (readonly)
12 13 14 |
# File 'lib/ring_sig/private_key.rb', line 12 def public_key @public_key end |
#value ⇒ Integer (readonly)
The integer value of this private key. A number between 0 and the group's order (non-inclusive).
9 10 11 |
# File 'lib/ring_sig/private_key.rb', line 9 def value @value end |
Class Method Details
.from_hex(hex_string, opts = {}) ⇒ PrivateKey
Creates a new instance of RingSig::PrivateKey from a hex string.
47 48 49 50 51 52 53 |
# File 'lib/ring_sig/private_key.rb', line 47 def self.from_hex(hex_string, opts = {}) group = opts.delete(:group) { RingSig.default_group } hash_algorithm = opts.delete(:hash_algorithm) { RingSig.default_hash_algorithm } raise ArgumentError, "Unknown opts: #{opts.keys.join(', ')}" unless opts.empty? self.from_octet([hex_string].pack('H*'), group: group, hash_algorithm: hash_algorithm) end |
.from_octet(octet_string, opts = {}) ⇒ PrivateKey
Creates a new instance of RingSig::PrivateKey from an octet string.
62 63 64 65 66 67 68 69 |
# File 'lib/ring_sig/private_key.rb', line 62 def self.from_octet(octet_string, opts = {}) group = opts.delete(:group) { RingSig.default_group } hash_algorithm = opts.delete(:hash_algorithm) { RingSig.default_hash_algorithm } raise ArgumentError, "Unknown opts: #{opts.keys.join(', ')}" unless opts.empty? value = ECDSA::Format::FieldElementOctetString.decode(octet_string, group.field) PrivateKey.new(value, group: group, hash_algorithm: hash_algorithm) end |
Instance Method Details
#==(other) ⇒ Boolean
Returns true if the private keys are equal.
127 128 129 130 |
# File 'lib/ring_sig/private_key.rb', line 127 def ==(other) return false unless other.is_a?(PrivateKey) value == other.value && group == other.group && hash_algorithm == other.hash_algorithm end |
#key_image ⇒ ECDSA::Point
Returns the key image.
117 118 119 |
# File 'lib/ring_sig/private_key.rb', line 117 def key_image @key_image ||= @hasher.hash_point(point) * value end |
#point ⇒ ECDSA::Point
Returns the public key's point.
122 123 124 |
# File 'lib/ring_sig/private_key.rb', line 122 def point public_key.point end |
#sign(message, foreign_keys) ⇒ Array(Signature, Array<PublicKey>)
Signs a message with this key's private key and a set of foreign public 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.
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/ring_sig/private_key.rb', line 97 def sign(, foreign_keys) raise ArgumentError "Foreign keys must all have the same group" unless foreign_keys.all?{ |e| e.group == group } = @hasher.hash_string() seed = @hasher.hash_array([value, ]) 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(&:public_key) signature = Signature.new(key_image, c_array, r_array, group: group, hash_algorithm: hash_algorithm) [signature, public_keys] end |
#to_hex ⇒ String
Encodes this private key into an octet string. The encoded data contains only the value. It does not contain the group or hash_algorithm.
75 76 77 |
# File 'lib/ring_sig/private_key.rb', line 75 def to_hex to_octet.unpack('H*').first end |
#to_octet ⇒ String
Encodes this public key into a hex string. The encoded data contains only the value. It does not contain the group or hash_algorithm.
83 84 85 |
# File 'lib/ring_sig/private_key.rb', line 83 def to_octet ECDSA::Format::FieldElementOctetString.encode(value, group.field) end |