class BLS::Fq12

Finite extension field over irreducible polynomial. Fq6(w) / (w2 - γ) where γ = v

Constants

FROBENIUS_COEFFICIENTS
ONE
ZERO

Attributes

coeffs[R]

Public Class Methods

from_tuple(t) click to toggle source
# File lib/bls/field.rb, line 418
def self.from_tuple(t)
  Fq12.new([Fq6.from_tuple(t[0...6]), Fq6.from_tuple(t[6...12])])
end
new(coeffs) click to toggle source
# File lib/bls/field.rb, line 412
def initialize(coeffs)
  raise ArgumentError, 'Expected array with 2 elements' unless coeffs.size == 2

  @coeffs = coeffs
end

Public Instance Methods

*(other)
Alias for: multiply
cyclotomic_exp(n) click to toggle source
# File lib/bls/field.rb, line 547
def cyclotomic_exp(n)
  z = Fq12::ONE
  i = BLS_X_LEN - 1
  while i >= 0
    z = z.cyclotomic_square
    z *= self unless BLS.bit_get(n, i).zero?
    i -= 1
  end
  z
end
cyclotomic_square() click to toggle source
# File lib/bls/field.rb, line 534
def cyclotomic_square
  c0, c1 = coeffs
  c0c0, c0c1, c0c2 = c0.coeffs
  c1c0, c1c1, c1c2 = c1.coeffs
  t3, t4 = fq4_square(c0c0, c1c1)
  t5, t6 = fq4_square(c1c0, c0c2)
  t7, t8 = fq4_square(c0c1, c1c2)
  t9 = t8.mul_by_non_residue
  Fq12.new([
             Fq6.new([(t3 - c0c0) * 2 + t3, (t5 - c0c1) * 2 + t5, (t7 - c0c2) * 2 + t7]),
             Fq6.new([(t9 + c1c0) * 2 + t9, (t4 + c1c1) * 2 + t4, (t6 + c1c2) * 2 + t6])])
end
final_exponentiate() click to toggle source
# File lib/bls/field.rb, line 522
def final_exponentiate
  t0 = frobenius_map(6) / self
  t1 = t0.frobenius_map(2) * t0
  t2 = t1.cyclotomic_exp(Curve::X).conjugate
  t3 = t1.cyclotomic_square.conjugate * t2
  t4 = t3.cyclotomic_exp(Curve::X).conjugate
  t5 = t4.cyclotomic_exp(Curve::X).conjugate
  t6 = t5.cyclotomic_exp(Curve::X).conjugate * t2.cyclotomic_square
  (t2 * t5).frobenius_map(2) * (t4 * t1).frobenius_map(3) *
    (t6 * t1.conjugate).frobenius_map(1) * t6.cyclotomic_exp(Curve::X).conjugate * t3.conjugate * t1
end
frobenius_map(power) click to toggle source
# File lib/bls/field.rb, line 510
def frobenius_map(power)
  c0, c1 = coeffs
  r0 = c0.frobenius_map(power)
  c1_0, c1_1, c1_2 = c1.frobenius_map(power).coeffs
  Fq12.new([
             r0,
             Fq6.new([
                       c1_0 * Fq12::FROBENIUS_COEFFICIENTS[power % 12],
                       c1_1 * Fq12::FROBENIUS_COEFFICIENTS[power % 12],
                       c1_2 * Fq12::FROBENIUS_COEFFICIENTS[power % 12]])])
end
invert() click to toggle source
# File lib/bls/field.rb, line 504
def invert
  c0, c1 = coeffs
  t = (c0.square - c1.square.mul_by_non_residue).invert
  Fq12.new([c0 * t, (c1 * t).negate])
end
multiply(other) click to toggle source
# File lib/bls/field.rb, line 476
def multiply(other)
  return Fq12.new([coeffs[0] * other, coeffs[1] * other]) if other.is_a?(Integer)

  c0, c1 = coeffs
  r0, r1 = other.coeffs
  t1 = c0 * r0
  t2 = c1 * r1
  Fq12.new([t1 + t2.mul_by_non_residue, (c0 + c1) * (r0 + r1) - (t1 + t2)])
end
Also aliased as: *
multiply_by_014(o0, o1, o4) click to toggle source
# File lib/bls/field.rb, line 487
def multiply_by_014(o0, o1, o4)
  c0, c1 = coeffs
  t0 = c0.multiply_by_01(o0, o1)
  t1 = c1.multiply_by_1(o4)
  Fq12.new([t1.mul_by_non_residue + t0, (c1 + c0).multiply_by_01(o0, o1 + o4) - t0 - t1])
end
multiply_by_fq2(other) click to toggle source
# File lib/bls/field.rb, line 494
def multiply_by_fq2(other)
  Fq12.new(coeffs.map{ |c| c.multiply_by_fq2(other) })
end
square() click to toggle source
# File lib/bls/field.rb, line 498
def square
  c0, c1 = coeffs
  ab = c0 * c1
  Fq12.new([(c1.mul_by_non_residue + c0) * (c0 + c1) - ab - ab.mul_by_non_residue, ab + ab])
end

Private Instance Methods

fq4_square(a, b) click to toggle source

@param [Fq2] a @param [Fq2] b @return [Array]

# File lib/bls/field.rb, line 563
def fq4_square(a, b)
  a2 = a.square
  b2 = b.square
  [b2.mul_by_non_residue + a2, (a + b).square - a2 - b2]
end