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