Module: BLS::H2C::G2

Defined in:
lib/bls/h2c.rb

Class Method Summary collapse

Class Method Details

.hash_to_field(message, random_oracle: true) ⇒ Array[Integer]

Convert hash to Field.

Parameters:

  • message (String)

    hash value with hex format.

Returns:

  • (Array[Integer])

    byte array.



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/bls/h2c.rb', line 38

def hash_to_field(message, random_oracle: true)
  degree = 2
  count = random_oracle ? 2 : 1
  len_in_bytes = count * degree * LENGTH
  pseudo_random_bytes = BLS::H2C.expand_message_xmd(message, len_in_bytes)
  u = Array.new(count)
  count.times do |i|
    e = Array.new(degree)
    degree.times do |j|
      elm_offset = LENGTH * (j + i * degree)
      tv = pseudo_random_bytes[elm_offset...(elm_offset + LENGTH)]
      e[j] = BLS.mod(BLS.os2ip(tv), Curve::P)
    end
    u[i] = e
  end
  u
end

.isogeny_map(x, y, z) ⇒ Object

3-isogeny map from Eā€™ to E Converts from Jacobi (xyz) to Projective (xyz) coordinates.



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/bls/h2c.rb', line 93

def isogeny_map(x, y, z)
  mapped = Array.new(4, Fp2::ZERO)
  z_powers = [z, z**2, z**3]
  ISOGENY_COEFFICIENTS.each.with_index do |k, i|
    mapped[i] = k[-1]
    arr = k[0...-1].reverse
    arr.each.with_index do |a, j|
      mapped[i] = mapped[i] * x + z_powers[j] * a
    end
  end
  mapped[2] *= y
  mapped[3] *= z
  z2 = mapped[1] * mapped[3]
  x2 = mapped[0] * mapped[3]
  y2 = mapped[1] * mapped[2]
  [x2, y2, z2]
end

.map_to_curve_sswu(t) ⇒ Object

Optimized SWU Map - Fp2 to G2ā€™: y^2 = x^3 + 240i * x + 1012 + 1012i

Raises:



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/bls/h2c.rb', line 57

def map_to_curve_sswu(t)
  iso_3_a = Fp2.new([0, 240])
  iso_3_b = Fp2.new([1012, 1012])
  iso_3_z = Fp2.new([-2, -1])
  t = Fp2.new(t) if t.is_a?(Array)
  t2 = t**2
  iso_3_z_t2 = iso_3_z * t2
  ztzt = iso_3_z_t2 + iso_3_z_t2**2
  denominator = (iso_3_a * ztzt).negate
  numerator = iso_3_b * (ztzt + Fp2::ONE)
  denominator = iso_3_z * iso_3_a if denominator.zero?
  v = denominator**3
  u = numerator**3 + iso_3_a * numerator * denominator**2 + iso_3_b * v
  success, sqrt_candidate_or_gamma = BLS.sqrt_div_fp2(u, v)
  y = success ? sqrt_candidate_or_gamma : nil
  sqrt_candidate_x1 = sqrt_candidate_or_gamma * t**3
  u = iso_3_z_t2**3 * u
  success2 = false
  Fp2::ETAS.each do |eta|
    eta_sqrt_candidate = eta * sqrt_candidate_x1
    temp = eta_sqrt_candidate**2 * v - u
    if temp.zero? && !success && !success2
      y = eta_sqrt_candidate
      success2 = true
    end
  end
  raise BLS::PointError, 'Hash to Curve - Optimized SWU failure' if !success && !success2

  numerator *= iso_3_z_t2 if success2
  y = y.negate if BLS.sgn0(t) != BLS.sgn0(y)
  y *= denominator
  [numerator, y, denominator]
end