class BLS::PointG2

Constants

BASE
MAX_BITS
ZERO

Attributes

precomputes[RW]

Public Class Methods

from_hex(hex) click to toggle source

Parse PointG1 from form hex. @param [String] hex hex value of PointG2. Currently, only uncompressed formats(196 bytes) are supported. @return [BLS::PointG2] PointG2 object. @raise [BLS::PointError]

# File lib/bls/point.rb, line 324
def self.from_hex(hex)
  bytes = [hex].pack('H*')
  point = case bytes.bytesize
          when 96
            raise PointError, 'Compressed format not supported yet.'
          when 192
            return ZERO unless (bytes[0].unpack1('H*').to_i(16) & (1 << 6)).zero?

            x1 = bytes[0...PUBLIC_KEY_LENGTH].unpack1('H*').to_i(16)
            x0 = bytes[PUBLIC_KEY_LENGTH...(2 * PUBLIC_KEY_LENGTH)].unpack1('H*').to_i(16)
            y1 = bytes[(2 * PUBLIC_KEY_LENGTH)...(3 * PUBLIC_KEY_LENGTH)].unpack1('H*').to_i(16)
            y0 = bytes[(3 * PUBLIC_KEY_LENGTH)..-1].unpack1('H*').to_i(16)
            PointG2.new(Fq2.new([x0, x1]), Fq2.new([y0, y1]), Fq2::ONE)
          else
            raise PointError, 'Invalid uncompressed point G2, expected 192 bytes.'
          end
  point.validate!
  point
end
hash_to_curve(message) click to toggle source

Convert hash to PointG2 @param [String] message a hash with hex format. @return [BLS::PointG2] point. @raise [BLS::PointError]

# File lib/bls/point.rb, line 348
def self.hash_to_curve(message)
  raise PointError, 'expected hex string' unless message[/^[a-fA-F0-9]*$/]

  u = BLS.hash_to_field(message, 2)
  q0 = PointG2.new(*BLS.isogeny_map_g2(*BLS.map_to_curve_sswu_g2(u[0])))
  q1 = PointG2.new(*BLS.isogeny_map_g2(*BLS.map_to_curve_sswu_g2(u[1])))
  r = q0 + q1
  BLS.clear_cofactor_g2(r)
end

Public Instance Methods

clear_pairing_precomputes() click to toggle source
# File lib/bls/point.rb, line 398
def clear_pairing_precomputes
  self.precomputes = nil
end
pairing_precomputes() click to toggle source
# File lib/bls/point.rb, line 402
def pairing_precomputes
  return precomputes if precomputes

  self.precomputes = calc_pairing_precomputes(*to_affine)
  precomputes
end
to_hex(compressed: false) click to toggle source
# File lib/bls/point.rb, line 358
def to_hex(compressed: false)
  raise ArgumentError, 'Not supported' if compressed

  if self == PointG2::ZERO
    (1 << 6).to_s(16) + '00' * (4 * PUBLIC_KEY_LENGTH - 1)
  else
    validate!
    x, y = to_affine.map(&:values)
    BLS.num_to_hex(x[1], PUBLIC_KEY_LENGTH) +
      BLS.num_to_hex(x[0], PUBLIC_KEY_LENGTH) +
      BLS.num_to_hex(y[1], PUBLIC_KEY_LENGTH) +
      BLS.num_to_hex(y[0], PUBLIC_KEY_LENGTH)
  end
end
to_signature() click to toggle source

Convert to signature with hex format. @return [String] signature with hex format.

# File lib/bls/point.rb, line 375
def to_signature
  if self == PointG2::ZERO
    sum = POW_2_383 + POW_2_382
    return BLS.num_to_hex(sum, PUBLIC_KEY_LENGTH) + BLS.num_to_hex(0, PUBLIC_KEY_LENGTH)
  end
  validate!
  x, y = to_affine.map(&:values)
  tmp = y[1] > 0 ? y[1] * 2 : y[0] * 2
  aflag1 = tmp / Curve::P
  z1 = x[1] + aflag1 * POW_2_381 + POW_2_383
  z2 = x[0]
  BLS.num_to_hex(z1, PUBLIC_KEY_LENGTH) + BLS.num_to_hex(z2, PUBLIC_KEY_LENGTH)
end
validate!() click to toggle source
# File lib/bls/point.rb, line 389
def validate!
  b = Fq2.new(Curve::B2)
  return if zero?

  left = y.pow(2) * z - x.pow(3)
  right = b * z.pow(3)
  raise PointError, 'Invalid point: not on curve over Fq2' unless left == right
end

Private Instance Methods

calc_pairing_precomputes(x, y) click to toggle source
# File lib/bls/point.rb, line 411
def calc_pairing_precomputes(x, y)
  q_x, q_y, q_z = [x, y, Fq2::ONE]
  r_x, r_y, r_z = [q_x, q_y, q_z]
  ell_coeff = []
  i = BLS_X_LEN - 2
  while i >= 0
    t0 = r_y.square
    t1 = r_z.square
    t2 = t1.multiply(3).multiply_by_b
    t3 = t2 * 3
    t4 = (r_y + r_z).square - t1 - t0
    ell_coeff << [t2 - t0, r_x.square * 3, t4.negate]
    r_x = (t0 - t3) * r_x * r_y / 2
    r_y = ((t0 + t3) / 2).square - t2.square * 3
    r_z = t0 * t4
    unless BLS.bit_get(Curve::X, i).zero?
      t0 = r_y - q_y * r_z
      t1 = r_x - q_x * r_z
      ell_coeff << [t0 * q_x - t1 * q_y, t0.negate, t1]
      t2 = t1.square
      t3 = t2 * t1
      t4 = t2 * r_x
      t5 = t3 - t4 * 2 + t0.square * r_z
      r_x = t1 * t5
      r_y = (t4 - t5) * t0 - t3 * r_y
      r_z *= t3
    end
    i -= 1
  end
  ell_coeff
end