class RingSig::Signature
Instances of this class represent RingSig
signatures.
Attributes
@return [Array]
@return [Hasher]
@return [ECDSA::Point]
@return [Array]
Public Class Methods
Creates a new instance of {Signature} from a der string.
@param der_string [String] @param hasher [Hasher] @return [Signature]
# File lib/ring_sig/signature.rb, line 36 def self.from_der(der_string, hasher) asn1 = OpenSSL::ASN1.decode(der_string) key_image = ECDSA::Format::PointOctetString.decode(asn1.value[0].value, hasher.group) c_array = asn1.value[1].value.map{|i| i.value.to_i} r_array = asn1.value[2].value.map{|i| i.value.to_i} Signature.new(key_image, c_array, r_array, hasher) end
Creates a new instance of {Signature} from a hex string.
@param hex_string [String] @param hasher [Hasher] @return [Signature]
# File lib/ring_sig/signature.rb, line 51 def self.from_hex(hex_string, hasher) Signature.from_der([hex_string].pack('H*'), hasher) end
Creates a new instance of {Signature}.
@param key_image
[ECDSA::Point] @param c_array
[Array<Integer>] @param r_array
[Array<Integer>] @param hasher [Hasher]
# File lib/ring_sig/signature.rb, line 22 def initialize(key_image, c_array, r_array, hasher) @key_image, @c_array, @r_array = key_image, c_array, r_array key_image.is_a?(ECDSA::Point) or raise ArgumentError, 'key_image is not an ECDSA::Point.' c_array.is_a?(Array) or raise ArgumentError, 'c_array is not an array.' r_array.is_a?(Array) or raise ArgumentError, 'r_array is not an array.' @hasher = hasher end
Public Instance Methods
Returns an array containing key image coordinates, c_array
, and r_array. @return (Array)
# File lib/ring_sig/signature.rb, line 109 def components key_image.coords + c_array + r_array end
Encodes this signature into a der string. The encoded data contains the key_image
, c_array
, and r_array. It does not contain the hasher.
@param opts [Hash] @option opts [Boolean] :compression (true) @return [String]
# File lib/ring_sig/signature.rb, line 61 def to_der(opts = {}) compression = opts.delete(:compression) { true } raise ArgumentError, "Unknown opts: #{opts.keys.join(', ')}" unless opts.empty? OpenSSL::ASN1::Sequence.new([ OpenSSL::ASN1::OctetString.new(ECDSA::Format::PointOctetString.encode(key_image, compression: compression)), OpenSSL::ASN1::Sequence.new(c_array.map{|i| OpenSSL::ASN1::Integer.new(i)}), OpenSSL::ASN1::Sequence.new(r_array.map{|i| OpenSSL::ASN1::Integer.new(i)}), ]).to_der end
Encodes this signature into a hex string. The encoded data contains the key_image
, c_array
, and r_array. It does not contain the hasher.
@param opts [Hash] @option opts [Boolean] :compression (true) @return [String]
# File lib/ring_sig/signature.rb, line 78 def to_hex(opts = {}) compression = opts.delete(:compression) { true } raise ArgumentError, "Unknown opts: #{opts.keys.join(', ')}" unless opts.empty? to_der(compression: compression).unpack('H*').first end
Verifies this signature against an ordered set of public keys.
@param message [String] @param public_keys [Array<PublicKey>] @return [Boolean] true if the signature verifies, false otherwise.
# File lib/ring_sig/signature.rb, line 90 def verify(message, public_keys) ll_array = [] rr_array = [] public_keys.each_with_index do |k, i| ll_array[i] = (hasher.group.generator * r_array[i]) + (k.point * c_array[i]) rr_array[i] = (hasher.hash_point(k.point) * (r_array[i]) + key_image * c_array[i]) end c_sum = c_array.inject{|a, b| a + b} % hasher.group.order message_digest = hasher.hash_string(message) challenge = hasher.hash_array([message_digest] + ll_array + rr_array) c_sum == challenge end