class JSON::JWK

def to_ec_key

def to_ec_key
  curve_name = case self[:crv]&.to_sym
  when :'P-256'
    'prime256v1'
  when :'P-384'
    'secp384r1'
  when :'P-521'
    'secp521r1'
  when :secp256k1
    'secp256k1'
  else
    raise UnknownAlgorithm.new('Unknown EC Curve')
  end
  x, y, d = [:x, :y, :d].collect do |key|
    if self[key]
      Base64.urlsafe_decode64(self[key])
    end
  end
  point = OpenSSL::PKey::EC::Point.new(
    OpenSSL::PKey::EC::Group.new(curve_name),
    OpenSSL::BN.new(['04' + x.unpack('H*').first + y.unpack('H*').first].pack('H*'), 2)
  )
  # Public key
  data_sequence = OpenSSL::ASN1::Sequence([
    OpenSSL::ASN1::Sequence([
      OpenSSL::ASN1::ObjectId("id-ecPublicKey"),
      OpenSSL::ASN1::ObjectId(curve_name)
    ]),
    OpenSSL::ASN1::BitString(point.to_octet_string(:uncompressed))
  ])
  if d
    # Private key
    data_sequence = OpenSSL::ASN1::Sequence([
      OpenSSL::ASN1::Integer(1),
      OpenSSL::ASN1::OctetString(OpenSSL::BN.new(d, 2).to_s(2)),
      OpenSSL::ASN1::ObjectId(curve_name, 0, :EXPLICIT),
      OpenSSL::ASN1::BitString(point.to_octet_string(:uncompressed), 1, :EXPLICIT)
    ])
  end
  OpenSSL::PKey::EC.new(data_sequence.to_der)
end