bls12-381 0.2.2 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/lib/bls/point.rb CHANGED
@@ -1,9 +1,18 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'bigdecimal'
4
+ require 'h2c'
4
5
 
5
6
  module BLS
6
7
 
8
+ # Point serialization flags
9
+ POINT_COMPRESSION_FLAG = 0x80
10
+ POINT_INFINITY_FLAG = 0x40
11
+ POINT_Y_FLAG = 0x20
12
+
13
+ autoload :PointG1, "bls/point/g1"
14
+ autoload :PointG2, "bls/point/g2"
15
+
7
16
  class PointError < StandardError; end
8
17
 
9
18
  # Abstract Point class that consist of projective coordinates.
@@ -224,240 +233,8 @@ module BLS
224
233
  end
225
234
  end
226
235
 
227
- class PointG1 < ProjectivePoint
228
-
229
- BASE = PointG1.new(Fq.new(Curve::G_X), Fq.new(Curve::G_Y), Fq::ONE)
230
- ZERO = PointG1.new(Fq::ONE, Fq::ONE, Fq::ZERO)
231
- MAX_BITS = Fq::MAX_BITS
232
-
233
- # Parse PointG1 from form hex.
234
- # @param [String] hex hex value of PointG1.
235
- # @return [PointG1]
236
- # @raise [BLS::PointError] Occurs when hex length does not match, or point does not on G1.
237
- def self.from_hex(hex)
238
- bytes = [hex].pack('H*')
239
- point = case bytes.bytesize
240
- when 48
241
- compressed_value = hex.to_i(16)
242
- b_flag = BLS.mod(compressed_value, POW_2_383) / POW_2_382
243
- return ZERO if b_flag == 1
244
-
245
- x = BLS.mod(compressed_value, POW_2_381)
246
- full_y = BLS.mod(x**3 + Fq.new(Curve::B).value, Curve::P)
247
- y = BLS.pow_mod(full_y, (Curve::P + 1) / 4, Curve::P)
248
- raise PointError, 'The given point is not on G1: y**2 = x**3 + b.' unless (BLS.pow_mod(y, 2, Curve::P) - full_y).zero?
249
-
250
- a_flag = BLS.mod(compressed_value, POW_2_382) / POW_2_381
251
- y = Curve::P - y unless ((y * 2) / Curve::P) == a_flag
252
- PointG1.new(Fq.new(x), Fq.new(y), Fq::ONE)
253
- when 96
254
- return ZERO unless (bytes[0].unpack1('H*').to_i(16) & (1 << 6)).zero?
255
-
256
- x = bytes[0...PUBLIC_KEY_LENGTH].unpack1('H*').to_i(16)
257
- y = bytes[PUBLIC_KEY_LENGTH..-1].unpack1('H*').to_i(16)
258
- PointG1.new(Fq.new(x), Fq.new(y), Fq::ONE)
259
- else
260
- raise PointError, 'Invalid point G1, expected 48 or 96 bytes.'
261
- end
262
- point.validate!
263
- point
264
- end
265
-
266
- def to_hex(compressed: false)
267
- if compressed
268
- if self == PointG1::ZERO
269
- hex = POW_2_383 + POW_2_382
270
- else
271
- x, y = to_affine
272
- flag = (y.value * 2) / Curve::P
273
- hex = x.value + flag * POW_2_381 + POW_2_383
274
- end
275
- BLS.num_to_hex(hex, PUBLIC_KEY_LENGTH)
276
- else
277
- if self == PointG1::ZERO
278
- (1 << 6).to_s(16) + '00' * (2 * PUBLIC_KEY_LENGTH - 1)
279
- else
280
- x, y = to_affine
281
- BLS.num_to_hex(x.value, PUBLIC_KEY_LENGTH) + BLS.num_to_hex(y.value, PUBLIC_KEY_LENGTH)
282
- end
283
- end
284
- end
285
-
286
- # Parse Point from private key.
287
- # @param [String|Integer] private_key a private key with hex or number.
288
- # @return [PointG1] G1Point corresponding to private keys.
289
- # @raise [BLS::Error] Occur when the private key is zero.
290
- def self.from_private_key(private_key)
291
- BASE * BLS.normalize_priv_key(private_key)
292
- end
293
-
294
- # Validate this point whether on curve over Fq.
295
- # @raise [PointError] Occur when this point not on curve over Fq.
296
- def validate!
297
- b = Fq.new(Curve::B)
298
- return if zero?
299
-
300
- left = y.pow(2) * z - x.pow(3)
301
- right = b * z.pow(3)
302
- raise PointError, 'Invalid point: not on curve over Fq' unless left == right
303
- end
304
-
305
- # Sparse multiplication against precomputed coefficients.
306
- # @param [PointG2] p
307
- def miller_loop(p)
308
- BLS.miller_loop(p.pairing_precomputes, to_affine)
309
- end
310
- end
311
-
312
- class PointG2 < ProjectivePoint
313
-
314
- attr_accessor :precomputes
315
-
316
- MAX_BITS = Fq2::MAX_BITS
317
- BASE = PointG2.new(Fq2.new(Curve::G2_X), Fq2.new(Curve::G2_Y), Fq2::ONE)
318
- ZERO = PointG2.new(Fq2::ONE, Fq2::ONE, Fq2::ZERO)
319
-
320
- # Parse PointG1 from form hex.
321
- # @param [String] hex hex value of PointG2. Currently, only uncompressed formats(196 bytes) are supported.
322
- # @return [BLS::PointG2] PointG2 object.
323
- # @raise [BLS::PointError]
324
- def self.from_hex(hex)
325
- bytes = [hex].pack('H*')
326
- point = case bytes.bytesize
327
- when 96
328
- raise PointError, 'Compressed format not supported yet.'
329
- when 192
330
- return ZERO unless (bytes[0].unpack1('H*').to_i(16) & (1 << 6)).zero?
331
-
332
- x1 = bytes[0...PUBLIC_KEY_LENGTH].unpack1('H*').to_i(16)
333
- x0 = bytes[PUBLIC_KEY_LENGTH...(2 * PUBLIC_KEY_LENGTH)].unpack1('H*').to_i(16)
334
- y1 = bytes[(2 * PUBLIC_KEY_LENGTH)...(3 * PUBLIC_KEY_LENGTH)].unpack1('H*').to_i(16)
335
- y0 = bytes[(3 * PUBLIC_KEY_LENGTH)..-1].unpack1('H*').to_i(16)
336
- PointG2.new(Fq2.new([x0, x1]), Fq2.new([y0, y1]), Fq2::ONE)
337
- else
338
- raise PointError, 'Invalid uncompressed point G2, expected 192 bytes.'
339
- end
340
- point.validate!
341
- point
342
- end
343
-
344
- # Parse Point from private key.
345
- # @param [String|Integer] private_key a private key with hex or number.
346
- # @return [PointG1] G1Point corresponding to private keys.
347
- # @raise [BLS::Error] Occur when the private key is zero.
348
- def self.from_private_key(private_key)
349
- BASE * BLS.normalize_priv_key(private_key)
350
- end
351
-
352
- # Convert hash to PointG2
353
- # @param [String] message a hash with hex format.
354
- # @return [BLS::PointG2] point.
355
- # @raise [BLS::PointError]
356
- def self.hash_to_curve(message)
357
- raise PointError, 'expected hex string' unless message[/^[a-fA-F0-9]*$/]
358
-
359
- u = BLS.hash_to_field(message, 2)
360
- q0 = PointG2.new(*BLS.isogeny_map_g2(*BLS.map_to_curve_sswu_g2(u[0])))
361
- q1 = PointG2.new(*BLS.isogeny_map_g2(*BLS.map_to_curve_sswu_g2(u[1])))
362
- r = q0 + q1
363
- BLS.clear_cofactor_g2(r)
364
- end
365
-
366
- def to_hex(compressed: false)
367
- raise ArgumentError, 'Not supported' if compressed
368
-
369
- if self == PointG2::ZERO
370
- (1 << 6).to_s(16) + '00' * (4 * PUBLIC_KEY_LENGTH - 1)
371
- else
372
- validate!
373
- x, y = to_affine.map(&:values)
374
- BLS.num_to_hex(x[1], PUBLIC_KEY_LENGTH) +
375
- BLS.num_to_hex(x[0], PUBLIC_KEY_LENGTH) +
376
- BLS.num_to_hex(y[1], PUBLIC_KEY_LENGTH) +
377
- BLS.num_to_hex(y[0], PUBLIC_KEY_LENGTH)
378
- end
379
- end
380
-
381
- # Convert to signature with hex format.
382
- # @return [String] signature with hex format.
383
- def to_signature
384
- if self == PointG2::ZERO
385
- sum = POW_2_383 + POW_2_382
386
- return BLS.num_to_hex(sum, PUBLIC_KEY_LENGTH) + BLS.num_to_hex(0, PUBLIC_KEY_LENGTH)
387
- end
388
- validate!
389
- x, y = to_affine.map(&:values)
390
- tmp = y[1] > 0 ? y[1] * 2 : y[0] * 2
391
- aflag1 = tmp / Curve::P
392
- z1 = x[1] + aflag1 * POW_2_381 + POW_2_383
393
- z2 = x[0]
394
- BLS.num_to_hex(z1, PUBLIC_KEY_LENGTH) + BLS.num_to_hex(z2, PUBLIC_KEY_LENGTH)
395
- end
396
-
397
- def validate!
398
- b = Fq2.new(Curve::B2)
399
- return if zero?
400
-
401
- left = y.pow(2) * z - x.pow(3)
402
- right = b * z.pow(3)
403
- raise PointError, 'Invalid point: not on curve over Fq2' unless left == right
404
- end
405
-
406
- def clear_pairing_precomputes
407
- self.precomputes = nil
408
- end
409
-
410
- def pairing_precomputes
411
- return precomputes if precomputes
412
-
413
- self.precomputes = calc_pairing_precomputes(*to_affine)
414
- precomputes
415
- end
416
-
417
- private
418
-
419
- def calc_pairing_precomputes(x, y)
420
- q_x, q_y, q_z = [x, y, Fq2::ONE]
421
- r_x, r_y, r_z = [q_x, q_y, q_z]
422
- ell_coeff = []
423
- i = BLS_X_LEN - 2
424
- while i >= 0
425
- t0 = r_y.square
426
- t1 = r_z.square
427
- t2 = t1.multiply(3).multiply_by_b
428
- t3 = t2 * 3
429
- t4 = (r_y + r_z).square - t1 - t0
430
- ell_coeff << [t2 - t0, r_x.square * 3, t4.negate]
431
- r_x = (t0 - t3) * r_x * r_y / 2
432
- r_y = ((t0 + t3) / 2).square - t2.square * 3
433
- r_z = t0 * t4
434
- unless BLS.bit_get(Curve::X, i).zero?
435
- t0 = r_y - q_y * r_z
436
- t1 = r_x - q_x * r_z
437
- ell_coeff << [t0 * q_x - t1 * q_y, t0.negate, t1]
438
- t2 = t1.square
439
- t3 = t2 * t1
440
- t4 = t2 * r_x
441
- t5 = t3 - t4 * 2 + t0.square * r_z
442
- r_x = t1 * t5
443
- r_y = (t4 - t5) * t0 - t3 * r_y
444
- r_z *= t3
445
- end
446
- i -= 1
447
- end
448
- ell_coeff
449
- end
450
- end
451
-
452
236
  module_function
453
237
 
454
- def clear_cofactor_g2(p)
455
- t1 = p.multiply_unsafe(Curve::X).negate
456
- t2 = p.from_affine_tuple(BLS.psi(*p.to_affine))
457
- p2 = p.from_affine_tuple(BLS.psi2(*p.double.to_affine))
458
- p2 - t2 + (t1 + t2).multiply_unsafe(Curve::X).negate - t1 - p
459
- end
460
-
461
238
  def norm_p1(point)
462
239
  point.is_a?(PointG1) ? point : PointG1.from_hex(point)
463
240
  end
@@ -466,52 +243,12 @@ module BLS
466
243
  point.is_a?(PointG2) ? point : PointG2.from_hex(point)
467
244
  end
468
245
 
469
- def norm_p2h(point)
470
- point.is_a?(PointG2) ? point : PointG2.hash_to_curve(point)
246
+ def norm_p1h(point)
247
+ point.is_a?(PointG1) ? point : PointG1.hash_to_curve(point)
471
248
  end
472
249
 
473
- # Convert hash to Field.
474
- # @param [String] message hash value with hex format.
475
- # @return [Array[Integer]] byte array.
476
- def hash_to_field(message, degree, random_oracle: true)
477
- count = random_oracle ? 2 : 1
478
- l = 64
479
- len_in_bytes = count * degree * l
480
- pseudo_random_bytes = BLS.expand_message_xmd(message, len_in_bytes)
481
- u = Array.new(count)
482
- count.times do |i|
483
- e = Array.new(degree)
484
- degree.times do |j|
485
- elm_offset = l * (j + i * degree)
486
- tv = pseudo_random_bytes[elm_offset...(elm_offset + l)]
487
- e[j] = BLS.mod(BLS.os2ip(tv), Curve::P)
488
- end
489
- u[i] = e
490
- end
491
- u
250
+ def norm_p2h(point)
251
+ point.is_a?(PointG2) ? point : PointG2.hash_to_curve(point)
492
252
  end
493
253
 
494
- # @param [String] message hash value with hex format.
495
- # @param [Integer] len_in_bytes length
496
- # @return [Array[Integer]] byte array.
497
- # @raise BLS::Error
498
- def expand_message_xmd(message, len_in_bytes)
499
- b_in_bytes = BigDecimal(SHA256_DIGEST_SIZE)
500
- r_in_bytes = b_in_bytes * 2
501
- ell = (BigDecimal(len_in_bytes) / b_in_bytes).ceil
502
- raise BLS::Error, 'Invalid xmd length' if ell > 255
503
-
504
- dst_prime = DST_LABEL.bytes + BLS.i2osp(DST_LABEL.bytesize, 1)
505
- z_pad = BLS.i2osp(0, r_in_bytes)
506
- l_i_b_str = BLS.i2osp(len_in_bytes, 2)
507
- b = Array.new(ell)
508
- payload = z_pad + [message].pack('H*').bytes + l_i_b_str + BLS.i2osp(0, 1) + dst_prime
509
- b_0 = Digest::SHA256.digest(payload.pack('C*'))
510
- b[0] = Digest::SHA256.digest((b_0.bytes + BLS.i2osp(1, 1) + dst_prime).pack('C*'))
511
- (1..ell).each do |i|
512
- args = BLS.bin_xor(b_0, b[i - 1]).bytes + BLS.i2osp(i + 1, 1) + dst_prime
513
- b[i] = Digest::SHA256.digest(args.pack('C*'))
514
- end
515
- b.map(&:bytes).flatten[0...len_in_bytes]
516
- end
517
254
  end
data/lib/bls/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module BLS
4
- VERSION = '0.2.2'
4
+ VERSION = '0.3.0'
5
5
  end
data/lib/bls.rb CHANGED
@@ -5,6 +5,7 @@ require 'bls/version'
5
5
  require 'bls/math'
6
6
  require 'bls/curve'
7
7
  require 'bls/field'
8
+ require 'bls/h2c'
8
9
  require 'bls/point'
9
10
  require 'bls/pairing'
10
11
 
@@ -19,82 +20,134 @@ module BLS
19
20
  PUBLIC_KEY_LENGTH = 48
20
21
  SHA256_DIGEST_SIZE = 32
21
22
 
22
- DST_LABEL = 'BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_NUL_'
23
-
24
23
  module_function
25
24
 
26
25
  # Generate BLS signature: s = pk x H(m)
27
- # @param [String] message Message digest(hash value with hex format) to be signed.
26
+ # @param [String] message Message digest(hex format) to be signed.
28
27
  # @param [Integer|String] private_key The private key used for signing. Integer or String(hex).
28
+ # @param [Symbol] sig_type Signature type, :g1 or :g2.
29
+ # If :g1 is specified, the signature is a point on G1 and the public key is a point on G2.
30
+ # If :g2 is specified, the signature is a point on G2 and the public key is a point on G1.
29
31
  # @return [PointG2] The signature point.
30
- def sign(message, private_key)
31
- msg_point = BLS.norm_p2h(message)
32
+ def sign(message, private_key, sig_type: :g2)
33
+ msg_point = case sig_type
34
+ when :g1
35
+ BLS.norm_p1h(message)
36
+ when :g2
37
+ BLS.norm_p2h(message)
38
+ else
39
+ raise Error, 'sig_type must be :g1 or :g2.'
40
+ end
32
41
  msg_point * BLS.normalize_priv_key(private_key)
33
42
  end
34
43
 
35
44
  # Generate public key from +private_key+.
36
45
  # @param [Integer|String] private_key The private key. Integer or String(hex).
37
- # @return [BLS::PointG1] public key.
38
- def get_public_key(private_key)
39
- PointG1.from_private_key(private_key)
46
+ # @param [Symbol] key_type Public key type, :g1 or :g2.
47
+ # @return [BLS::PointG1|BLS::PointG2] public key.
48
+ def get_public_key(private_key, key_type: :g1)
49
+ case key_type
50
+ when :g1
51
+ PointG1.from_private_key(private_key)
52
+ when :g2
53
+ PointG2.from_private_key(private_key)
54
+ else
55
+ raise Error, 'key_type must be :g1 or :g2.'
56
+ end
40
57
  end
41
58
 
42
- # Verify BLS signature.
43
- # @param [String] signature
59
+ # Verify BLS signature. Verify one of the following:
60
+ # * Public key is a point on G1, signature is a point on G2 or
61
+ # * Public key is a point on G2, signature is a point on G1.
62
+ # @param [BLS::PointG1|BLS::PointG2] signature
44
63
  # @param [String] message Message digest(hash value with hex format) to be verified.
45
- # @param [String|BLS::PointG1] public_key Public key with hex format or PointG1.
64
+ # @param [BLS::PointG2|BLS::PointG1] public_key Public key with hex format or PointG1.
46
65
  # @return [Boolean] verification result.
47
66
  def verify(signature, message, public_key)
48
- p = BLS.norm_p1(public_key)
49
- hm = BLS.norm_p2h(message)
50
- g = PointG1::BASE
51
- s = BLS.norm_p2(signature)
52
- ephm = BLS.pairing(p.negate, hm, with_final_exp: false)
53
- egs = BLS.pairing(g, s, with_final_exp: false)
67
+ unless signature.is_a?(PointG1) && public_key.is_a?(PointG2) ||
68
+ signature.is_a?(PointG2) && public_key.is_a?(PointG1)
69
+ raise BLS::Error, 'Invalid signature or public key. If the public key is PointG1, the signature must be an element of Point::G2 or vice versa.'
70
+ end
71
+ g = public_key.is_a?(PointG1) ? PointG1::BASE : PointG2::BASE
72
+ ephm = if public_key.is_a?(PointG1)
73
+ hm = BLS.norm_p2h(message)
74
+ BLS.pairing(public_key.negate, hm, with_final_exp: false)
75
+ else
76
+ hm = BLS.norm_p1h(message)
77
+ BLS.pairing(hm, public_key.negate, with_final_exp: false)
78
+ end
79
+ egs = if public_key.is_a?(PointG1)
80
+ BLS.pairing(g, signature, with_final_exp: false)
81
+ else
82
+ BLS.pairing(signature, g, with_final_exp: false)
83
+ end
54
84
  exp = (egs * ephm).final_exponentiate
55
- exp == Fq12::ONE
85
+ exp == Fp12::ONE
56
86
  end
57
87
 
58
88
  # Aggregate multiple public keys.
59
- # @param [Array[String]] public_keys the list of public keys.
60
- # @return [BLS::PointG1] aggregated public key.
89
+ # @param [Array[BLS::PointG1]|Array[BLS::PointG2]] public_keys the list of public keys.
90
+ # @return [BLS::PointG1|BLS::PointG2] aggregated public key.
61
91
  def aggregate_public_keys(public_keys)
62
92
  raise BLS::Error, 'Expected non-empty array.' if public_keys.empty?
63
-
64
- public_keys.map { |p| BLS.norm_p1(p) }.inject(PointG1::ZERO) { |sum, p| sum + p }
93
+ g1_flag = public_keys.first.is_a?(PointG1)
94
+ sum = g1_flag ? PointG1::ZERO : PointG2::ZERO
95
+ public_keys.each do |pubkey|
96
+ if g1_flag && !pubkey.is_a?(PointG1) || !g1_flag && !pubkey.is_a?(PointG2)
97
+ raise BLS::Error, 'Point G1 and G2 are mixed.'
98
+ end
99
+ sum += pubkey
100
+ end
101
+ sum
65
102
  end
66
103
 
67
104
  # Aggregate multiple signatures.
68
105
  # e(G, S) = e(G, sum(n)Si) = mul(n)(e(G, Si))
69
- # @param [Array[String|BLS::PointG2]] signatures multiple signatures.
70
- # @return [BLS::PointG2] aggregated signature.
106
+ # @param [Array[BLS::PointG2]|Array[BLS::PointG2]] signatures multiple signatures.
107
+ # @return [BLS::PointG2|BLS::PointG1] aggregated signature.
71
108
  def aggregate_signatures(signatures)
72
109
  raise BLS::Error, 'Expected non-empty array.' if signatures.empty?
73
110
 
74
- signatures.map { |s| BLS.norm_p2(s) }.inject(PointG2::ZERO) { |sum, s| sum + s }
111
+ g2_flag = signatures.first.is_a?(PointG2)
112
+ sum = g2_flag ? PointG2::ZERO : PointG1::ZERO
113
+ signatures.each do |signature|
114
+ if g2_flag && !signature.is_a?(PointG2) || !g2_flag && !signature.is_a?(PointG1)
115
+ raise BLS::Error, 'Signature G1 and G2 are mixed.'
116
+ end
117
+ sum += signature
118
+ end
119
+ sum
75
120
  end
76
121
 
77
122
  # Verify aggregated signature.
78
- # @param [BLS::PointG2] signature aggregated signature.
123
+ # @param [BLS::PointG2|BLS::PointG1] signature aggregated signature(BLS::PointG2 or BLS::PointG1).
79
124
  # @param [Array[String]] messages the list of message.
80
- # @param [Array[String|BLS::PointG1]] public_keys the list of public keys with hex or BLS::PointG1 format.
125
+ # @param [Array[BLS::PointG1]|Array[BLS::PointG2]] public_keys the list of public keys(BLS::PointG1 or BLS::PointG2).
81
126
  # @return [Boolean] verification result.
82
127
  def verify_batch(signature, messages, public_keys)
83
128
  raise BLS::Error, 'Expected non-empty array.' if messages.empty?
84
129
  raise BLS::Error, 'Public keys count should equal msg count.' unless messages.size == public_keys.size
85
130
 
86
- n_message = messages.map { |m| BLS.norm_p2h(m) }
87
- n_public_keys = public_keys.map { |p| BLS.norm_p1(p) }
131
+ sig_g2_flag = signature.is_a?(PointG2)
132
+ public_keys.each do |public_key|
133
+ if sig_g2_flag && !public_key.is_a?(PointG1) || !sig_g2_flag && !public_key.is_a?(PointG2)
134
+ raise BLS::Error, "Public key must be #{sig_g2_flag ? 'PointG1' : 'PointG2'}"
135
+ end
136
+ end
137
+
138
+ n_message = messages.map { |m| sig_g2_flag ? BLS.norm_p2h(m) : BLS.norm_p1h(m)}
88
139
  paired = []
140
+ zero = sig_g2_flag ? PointG1::ZERO : PointG2::ZERO
89
141
  n_message.each do |message|
90
- group_pubkey = n_message.each_with_index.inject(PointG1::ZERO)do|group_pubkey, (sub_message, i)|
91
- sub_message == message ? group_pubkey + n_public_keys[i] : group_pubkey
142
+ group_pubkey = n_message.each_with_index.inject(zero)do|group_pubkey, (sub_message, i)|
143
+ sub_message == message ? group_pubkey + public_keys[i] : group_pubkey
92
144
  end
93
- paired << BLS.pairing(group_pubkey, message, with_final_exp: false)
145
+ paired << (sig_g2_flag ? BLS.pairing(group_pubkey, message, with_final_exp: false) :
146
+ BLS.pairing(message, group_pubkey, with_final_exp: false))
94
147
  end
95
- sig = BLS.norm_p2(signature)
96
- paired << BLS.pairing(PointG1::BASE.negate, sig, with_final_exp: false)
97
- product = paired.inject(Fq12::ONE) { |a, b| a * b }
98
- product.final_exponentiate == Fq12::ONE
148
+ paired << (sig_g2_flag ? BLS.pairing(PointG1::BASE.negate, signature, with_final_exp: false) :
149
+ BLS.pairing(signature, PointG2::BASE.negate, with_final_exp: false))
150
+ product = paired.inject(Fp12::ONE) { |a, b| a * b }
151
+ product.final_exponentiate == Fp12::ONE
99
152
  end
100
153
  end
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bls12-381
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shigeyuki Azuchi
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-01-26 00:00:00.000000000 Z
11
+ date: 2023-07-21 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: h2c
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 0.2.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 0.2.0
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: bundler
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -61,9 +75,12 @@ files:
61
75
  - lib/bls.rb
62
76
  - lib/bls/curve.rb
63
77
  - lib/bls/field.rb
78
+ - lib/bls/h2c.rb
64
79
  - lib/bls/math.rb
65
80
  - lib/bls/pairing.rb
66
81
  - lib/bls/point.rb
82
+ - lib/bls/point/g1.rb
83
+ - lib/bls/point/g2.rb
67
84
  - lib/bls/version.rb
68
85
  homepage: https://github.com/azuchi/bls12-381
69
86
  licenses: