lib/cose/key/ec2.rb in cose-0.5.0 vs lib/cose/key/ec2.rb in cose-0.6.0

- old
+ new

@@ -1,20 +1,15 @@ # frozen_string_literal: true -require "cose/key/base" +require "cose/key/curve_key" require "openssl" module COSE module Key - class EC2 < Base - ALG_LABEL = 3 + class EC2 < CurveKey + LABEL_Y = -3 - CRV_LABEL = -1 - D_LABEL = -4 - X_LABEL = -2 - Y_LABEL = -3 - KTY_EC2 = 2 CRV_P256 = 1 CRV_P384 = 2 CRV_P521 = 3 @@ -22,10 +17,16 @@ CRV_P256 => "prime256v1", CRV_P384 => "secp384r1", CRV_P521 => "secp521r1" }.freeze + def self.enforce_type(map) + if map[LABEL_KTY] != KTY_EC2 + raise "Not an EC2 key" + end + end + def self.from_pkey(pkey) curve = PKEY_CURVES.key(pkey.group.curve_name) || raise("Unsupported EC curve #{pkey.group.curve_name}") case pkey when OpenSSL::PKey::EC::Point @@ -40,76 +41,61 @@ if public_key bytes = public_key.to_bn.to_s(2)[1..-1] coordinate_length = bytes.size / 2 - x_coordinate = bytes[0..(coordinate_length - 1)] - y_coordinate = bytes[coordinate_length..-1] + x = bytes[0..(coordinate_length - 1)] + y = bytes[coordinate_length..-1] end if private_key - d_coordinate = private_key.to_s(2) + d = private_key.to_s(2) end - new(curve: curve, x_coordinate: x_coordinate, y_coordinate: y_coordinate, d_coordinate: d_coordinate) + new(crv: curve, x: x, y: y, d: d) end - attr_reader :algorithm, :curve, :d_coordinate, :x_coordinate, :y_coordinate + attr_reader :y - def initialize(algorithm: nil, curve:, d_coordinate: nil, x_coordinate:, y_coordinate:) - if !curve - raise ArgumentError, "Required curve is missing" - elsif !x_coordinate - raise ArgumentError, "Required x-coordinate is missing" - elsif !y_coordinate - raise ArgumentError, "Required y-coordinate is missing" + def initialize(y: nil, **keyword_arguments) # rubocop:disable Naming/UncommunicativeMethodParamName + if (!y || !keyword_arguments[:x]) && !keyword_arguments[:d] + raise ArgumentError, "Both x and y are required if d is missing" else - @algorithm = algorithm - @curve = curve - @d_coordinate = d_coordinate - @x_coordinate = x_coordinate - @y_coordinate = y_coordinate + super(**keyword_arguments) + + @y = y end end - def serialize - CBOR.encode( + def map + map = super.merge( Base::LABEL_KTY => KTY_EC2, - CRV_LABEL => curve, - X_LABEL => x_coordinate, - Y_LABEL => y_coordinate, - D_LABEL => d_coordinate + LABEL_Y => y, ) + + map.reject { |_k, v| v.nil? } end def to_pkey - if PKEY_CURVES[curve] - group = OpenSSL::PKey::EC::Group.new(PKEY_CURVES[curve]) + if PKEY_CURVES[crv] + group = OpenSSL::PKey::EC::Group.new(PKEY_CURVES[crv]) pkey = OpenSSL::PKey::EC.new(group) - public_key_bn = OpenSSL::BN.new("\x04" + x_coordinate + y_coordinate, 2) + public_key_bn = OpenSSL::BN.new("\x04" + x + y, 2) public_key_point = OpenSSL::PKey::EC::Point.new(group, public_key_bn) pkey.public_key = public_key_point - if d_coordinate - pkey.private_key = OpenSSL::BN.new(d_coordinate, 2) + if d + pkey.private_key = OpenSSL::BN.new(d, 2) end pkey else - raise "Unsupported curve #{curve}" + raise "Unsupported curve #{crv}" end end - def self.from_map(map) - enforce_type(map, KTY_EC2, "Not an EC2 key") - - new( - algorithm: map[ALG_LABEL], - curve: map[CRV_LABEL], - d_coordinate: map[D_LABEL], - x_coordinate: map[X_LABEL], - y_coordinate: map[Y_LABEL] - ) + def self.keyword_arguments_for_initialize(map) + super.merge(y: map[LABEL_Y]) end end end end