class SSHKey

def ecdsa_bits(ssh_type, identifier, q)

def ecdsa_bits(ssh_type, identifier, q)
  raise PublicKeyError, "invalid ssh type" unless ssh_type == "ecdsa-sha2-#{identifier}"
  len_q = q.length
  compression_octet = q.slice(0, 1)
  if compression_octet == "\x04"
    # Point compression is off
    # Summary from https://www.secg.org/sec1-v2.pdf "2.3.3  Elliptic-Curve-Point-to-Octet-String Conversion"
    # - the leftmost octet indicates that point compression is off
    #   (first octet 0x04 as specified in "3.3. Output M = 04 base 16 ‖ X ‖ Y.")
    # - the remainder of the octet string contains the x-coordinate followed by the y-coordinate.
    len_x = (len_q - 1) / 2
  else
    # Point compression is on
    # Summary from https://www.secg.org/sec1-v2.pdf "2.3.3  Elliptic-Curve-Point-to-Octet-String Conversion"
    # - the compressed y-coordinate is recovered from the leftmost octet
    # - the x-coordinate is recovered from the remainder of the octet string
    raise PublicKeyError, "invalid compression octet" unless compression_octet == "\x02" || compression_octet == "\x03"
    len_x = len_q - 1
  end
  # https://www.secg.org/sec2-v2.pdf "2.1  Properties of Elliptic Curve Domain Parameters over Fp" defines
  # five discrete bit lengths: 192, 224, 256, 384, 521
  # These bit lengths can be ascertained from the length of the packed x-coordinate.
  # Alternatively, these bit lengths can be derived from their associated prime constants using Math.log2(prime).ceil
  # against the prime constants defined in https://www.secg.org/sec2-v2.pdf
  case len_x
  when 24 then bits = 192
  when 28 then bits = 224
  when 32 then bits = 256
  when 48 then bits = 384
  when 66 then bits = 521
  else
    raise PublicKeyError, "invalid x-coordinate length #{len_x}"
  end
  raise PublicKeyError, "invalid identifier #{identifier}" unless identifier =~ /#{bits}/
  return bits
end