Class: BLS::Fp2

Inherits:
Object
  • Object
show all
Includes:
FQP
Defined in:
lib/bls/field.rb

Overview

Finite extension field over irreducible polynomial. Fp(u) / (u^2 - β) where β = -1

Constant Summary collapse

RV1 =

For Fp2 roots of unity.

0x6af0e0437ff400b6831e36d6bd17ffe48395dabc2d3435e77f76e17009241c5ee67992f72ec05f4c81084fbede3cc09
EV1 =
0x699be3b8c6870965e5bf892ad5d2cc7b0e85a117402dfd83b7f4a947e02d978498255a2aaec0ac627b5afbdf1bf1c90
EV2 =
0x8157cd83046453f5dd0972b6e3949e4288020b5b8a9cc99ca07e27089a2ce2436d965026adad3ef7baba37f2183e9b5
EV3 =
0xab1c2ffdd6c253ca155231eb3e71ba044fd562f6f72bc5bad5ec46a0b7a3b0247cf08ce6c6317f40edbc653a72dee17
EV4 =
0xaa404866706722864480885d68ad0ccac1967c7544b447873cc37e0181271e006df72162a3d3e0287bf597fbf7f8fc1
ORDER =
BLS::Curve::P2
MAX_BITS =
Curve::P2.bit_length
COFACTOR =
BLS::Curve::H2
ROOT =
Fp.new(-1)
ZERO =
Fp2.new([0, 0])
ONE =
Fp2.new([1, 0])
ROOTS_OF_UNITY =

Eighth roots of unity, used for computing square roots in Fp2.

[
  Fp2.new([1, 0]),
  Fp2.new([RV1, -RV1]),
  Fp2.new([0, 1]),
  Fp2.new([RV1, RV1]),
  Fp2.new([-1, 0]),
  Fp2.new([-RV1, RV1]),
  Fp2.new([0, -1]),
  Fp2.new([-RV1, -RV1])
].freeze
ETAS =

eta values, used for computing sqrt(g(X1(t)))

[
  Fp2.new([EV1, EV2]),
  Fp2.new([-EV2, EV1]),
  Fp2.new([EV3, EV4]),
  Fp2.new([-EV4, EV3])
].freeze
FROBENIUS_COEFFICIENTS =
[
  Fp.new(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001),
  Fp.new(0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaaa)
].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from FQP

#==, #add, #conjugate, #div, #negate, #pow, #subtract, #to_bytes, #to_hex, #zero?

Constructor Details

#initialize(coeffs) ⇒ Fp2

Returns a new instance of Fp2.

Raises:

  • (ArgumentError)


203
204
205
206
207
# File 'lib/bls/field.rb', line 203

def initialize(coeffs)
  raise ArgumentError, 'Expected array with 2 elements' unless coeffs.size == 2

  @coeffs = coeffs.map { |c| c.is_a?(Integer) ? Fp.new(c) : c }
end

Instance Attribute Details

#coeffsObject (readonly)

Returns the value of attribute coeffs.



201
202
203
# File 'lib/bls/field.rb', line 201

def coeffs
  @coeffs
end

Instance Method Details

#frobenius_map(power) ⇒ Object

Raises to q**i -th power



284
285
286
# File 'lib/bls/field.rb', line 284

def frobenius_map(power)
  Fp2.new([coeffs[0], coeffs[1] * Fp2::FROBENIUS_COEFFICIENTS[power % 2]])
end

#invertObject



277
278
279
280
281
# File 'lib/bls/field.rb', line 277

def invert
  a, b = values
  factor = Fp.new(a * a + b * b).invert
  Fp2.new([factor * a, factor * -b])
end

#mul_by_non_residueObject



288
289
290
291
# File 'lib/bls/field.rb', line 288

def mul_by_non_residue
  c0, c1 = coeffs
  Fp2.new([c0 - c1, c0 + c1])
end

#multiply(other) ⇒ Object Also known as: *



266
267
268
269
270
271
272
273
274
# File 'lib/bls/field.rb', line 266

def multiply(other)
  return Fp2.new(coeffs.map { |c| c * other }) if other.is_a?(Integer)

  c0, c1 = coeffs
  r0, r1 = other.coeffs
  t1 = c0 * r0
  t2 = c1 * r1
  Fp2.new([t1 - t2, ((c0 + c1) * (r0 + r1)) - (t1 + t2)])
end

#multiply_by_bObject



293
294
295
296
297
298
# File 'lib/bls/field.rb', line 293

def multiply_by_b
  c0, c1 = coeffs
  t0 = c0 * 4
  t1 = c1 * 4
  Fp2.new([t0 - t1, t0 + t1])
end

#sqrtObject

Raises:



251
252
253
254
255
256
257
258
259
260
261
262
263
264
# File 'lib/bls/field.rb', line 251

def sqrt
  candidate = pow((Fp2::ORDER + 8) / 16)
  check = candidate.square / self
  r = ROOTS_OF_UNITY
  divisor = [r[0], r[2], r[4], r[6]].find { |x| x == check }
  return nil unless divisor
  root = r[r.index(divisor) / 2]
  raise Error, 'Invalid root' unless root
  x1 = candidate / root
  x2 = x1.negate
  re1, im1 = x1.coeffs
  re2, im2 = x2.coeffs
  im1.value > im2.value || (im1 == im2 && re1.value > re2.value) ? x1 : x2
end

#squareObject



242
243
244
245
246
247
248
249
# File 'lib/bls/field.rb', line 242

def square
  c0 = coeffs[0]
  c1 = coeffs[1]
  a = c0 + c1
  b = c0 - c1
  c = c0 + c0
  Fp2.new([a * b, c * c1])
end

#valuesObject



238
239
240
# File 'lib/bls/field.rb', line 238

def values
  coeffs.map(&:value)
end