bls12-381 0.2.1 → 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.
- checksums.yaml +4 -4
- data/.github/workflows/main.yml +9 -1
- data/README.md +5 -3
- data/bls12-381.gemspec +1 -1
- data/lib/bls/field.rb +172 -136
- data/lib/bls/h2c.rb +114 -0
- data/lib/bls/math.rb +4 -61
- data/lib/bls/pairing.rb +1 -1
- data/lib/bls/point/g1.rb +105 -0
- data/lib/bls/point/g2.rb +188 -0
- data/lib/bls/point.rb +13 -276
- data/lib/bls/version.rb +1 -1
- data/lib/bls.rb +89 -36
- metadata +19 -2
data/lib/bls/field.rb
CHANGED
@@ -13,10 +13,6 @@ module BLS
|
|
13
13
|
self.class.new(-value)
|
14
14
|
end
|
15
15
|
|
16
|
-
def ==(other)
|
17
|
-
value == other.value
|
18
|
-
end
|
19
|
-
|
20
16
|
def invert
|
21
17
|
x0 = 1
|
22
18
|
x1 = 0
|
@@ -63,26 +59,43 @@ module BLS
|
|
63
59
|
multiply(v)
|
64
60
|
end
|
65
61
|
alias / div
|
62
|
+
|
63
|
+
def to_s
|
64
|
+
value.to_s
|
65
|
+
end
|
66
|
+
|
67
|
+
def ==(other)
|
68
|
+
return false unless other.is_a?(self.class)
|
69
|
+
value == other.value
|
70
|
+
end
|
66
71
|
end
|
67
72
|
|
68
73
|
# Finite field over q.
|
69
|
-
class
|
74
|
+
class Fp
|
70
75
|
include Field
|
71
76
|
|
72
77
|
ORDER = BLS::Curve::P
|
73
78
|
MAX_BITS = Curve::P.bit_length
|
79
|
+
BYTES_LEN = (MAX_BITS / 8.0).ceil
|
74
80
|
|
75
81
|
attr_reader :value
|
76
82
|
|
77
83
|
def initialize(value)
|
78
|
-
raise ArgumentError, '
|
84
|
+
raise ArgumentError, 'value must be Integer.' unless value.is_a?(Integer)
|
79
85
|
|
80
86
|
@value = BLS.mod(value, ORDER)
|
81
87
|
end
|
82
88
|
|
83
|
-
ZERO =
|
84
|
-
ONE =
|
89
|
+
ZERO = Fp.new(0)
|
90
|
+
ONE = Fp.new(1)
|
85
91
|
|
92
|
+
def to_bytes
|
93
|
+
[to_hex].pack('H*')
|
94
|
+
end
|
95
|
+
|
96
|
+
def to_hex
|
97
|
+
value.to_s(16).rjust(2 * BYTES_LEN, '0')
|
98
|
+
end
|
86
99
|
end
|
87
100
|
|
88
101
|
# Finite field over r.
|
@@ -94,7 +107,7 @@ module BLS
|
|
94
107
|
attr_reader :value
|
95
108
|
|
96
109
|
def initialize(value)
|
97
|
-
raise ArgumentError, '
|
110
|
+
raise ArgumentError, 'value must be Integer.' unless value.is_a?(Integer)
|
98
111
|
|
99
112
|
@value = BLS.mod(value, ORDER)
|
100
113
|
end
|
@@ -102,10 +115,6 @@ module BLS
|
|
102
115
|
ZERO = Fr.new(0)
|
103
116
|
ONE = Fr.new(1)
|
104
117
|
|
105
|
-
def legendre
|
106
|
-
pow((order - 1) / 2)
|
107
|
-
end
|
108
|
-
|
109
118
|
end
|
110
119
|
|
111
120
|
# Module for a field over polynomial.
|
@@ -131,7 +140,7 @@ module BLS
|
|
131
140
|
alias - subtract
|
132
141
|
|
133
142
|
def div(other)
|
134
|
-
inv = other.is_a?(Integer) ?
|
143
|
+
inv = other.is_a?(Integer) ? Fp.new(other).invert.value : other.invert
|
135
144
|
multiply(inv)
|
136
145
|
end
|
137
146
|
alias / div
|
@@ -159,14 +168,26 @@ module BLS
|
|
159
168
|
def conjugate
|
160
169
|
self.class.new([coeffs[0], coeffs[1].negate])
|
161
170
|
end
|
171
|
+
|
172
|
+
# Convert to byte string.
|
173
|
+
# @return [String]
|
174
|
+
def to_bytes
|
175
|
+
[to_hex].pack('H*')
|
176
|
+
end
|
177
|
+
|
178
|
+
# Convert to hex string.
|
179
|
+
# @return [String]
|
180
|
+
def to_hex
|
181
|
+
coeffs.map(&:to_hex).join
|
182
|
+
end
|
162
183
|
end
|
163
184
|
|
164
185
|
# Finite extension field over irreducible polynomial.
|
165
|
-
#
|
166
|
-
class
|
186
|
+
# Fp(u) / (u^2 - β) where β = -1
|
187
|
+
class Fp2
|
167
188
|
include FQP
|
168
189
|
|
169
|
-
# For
|
190
|
+
# For Fp2 roots of unity.
|
170
191
|
RV1 = 0x6af0e0437ff400b6831e36d6bd17ffe48395dabc2d3435e77f76e17009241c5ee67992f72ec05f4c81084fbede3cc09
|
171
192
|
EV1 = 0x699be3b8c6870965e5bf892ad5d2cc7b0e85a117402dfd83b7f4a947e02d978498255a2aaec0ac627b5afbdf1bf1c90
|
172
193
|
EV2 = 0x8157cd83046453f5dd0972b6e3949e4288020b5b8a9cc99ca07e27089a2ce2436d965026adad3ef7baba37f2183e9b5
|
@@ -182,36 +203,36 @@ module BLS
|
|
182
203
|
def initialize(coeffs)
|
183
204
|
raise ArgumentError, 'Expected array with 2 elements' unless coeffs.size == 2
|
184
205
|
|
185
|
-
@coeffs = coeffs.map { |c| c.is_a?(Integer) ?
|
206
|
+
@coeffs = coeffs.map { |c| c.is_a?(Integer) ? Fp.new(c) : c }
|
186
207
|
end
|
187
208
|
|
188
|
-
ROOT =
|
189
|
-
ZERO =
|
190
|
-
ONE =
|
209
|
+
ROOT = Fp.new(-1)
|
210
|
+
ZERO = Fp2.new([0, 0])
|
211
|
+
ONE = Fp2.new([1, 0])
|
191
212
|
|
192
|
-
# Eighth roots of unity, used for computing square roots in
|
213
|
+
# Eighth roots of unity, used for computing square roots in Fp2.
|
193
214
|
ROOTS_OF_UNITY = [
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
215
|
+
Fp2.new([1, 0]),
|
216
|
+
Fp2.new([RV1, -RV1]),
|
217
|
+
Fp2.new([0, 1]),
|
218
|
+
Fp2.new([RV1, RV1]),
|
219
|
+
Fp2.new([-1, 0]),
|
220
|
+
Fp2.new([-RV1, RV1]),
|
221
|
+
Fp2.new([0, -1]),
|
222
|
+
Fp2.new([-RV1, -RV1])
|
202
223
|
].freeze
|
203
224
|
|
204
225
|
# eta values, used for computing sqrt(g(X1(t)))
|
205
226
|
ETAS = [
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
227
|
+
Fp2.new([EV1, EV2]),
|
228
|
+
Fp2.new([-EV2, EV1]),
|
229
|
+
Fp2.new([EV3, EV4]),
|
230
|
+
Fp2.new([-EV4, EV3])
|
210
231
|
].freeze
|
211
232
|
|
212
233
|
FROBENIUS_COEFFICIENTS = [
|
213
|
-
|
214
|
-
|
234
|
+
Fp.new(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001),
|
235
|
+
Fp.new(0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaaa)
|
215
236
|
].freeze
|
216
237
|
|
217
238
|
def values
|
@@ -224,47 +245,62 @@ module BLS
|
|
224
245
|
a = c0 + c1
|
225
246
|
b = c0 - c1
|
226
247
|
c = c0 + c0
|
227
|
-
|
248
|
+
Fp2.new([a * b, c * c1])
|
249
|
+
end
|
250
|
+
|
251
|
+
def sqrt
|
252
|
+
candidate = pow((Fp2::ORDER + 8) / 16)
|
253
|
+
check = candidate.square / self
|
254
|
+
r = ROOTS_OF_UNITY
|
255
|
+
divisor = [r[0], r[2], r[4], r[6]].find { |x| x == check }
|
256
|
+
return nil unless divisor
|
257
|
+
root = r[r.index(divisor) / 2]
|
258
|
+
raise Error, 'Invalid root' unless root
|
259
|
+
x1 = candidate / root
|
260
|
+
x2 = x1.negate
|
261
|
+
re1, im1 = x1.coeffs
|
262
|
+
re2, im2 = x2.coeffs
|
263
|
+
im1.value > im2.value || (im1 == im2 && re1.value > re2.value) ? x1 : x2
|
228
264
|
end
|
229
265
|
|
230
266
|
def multiply(other)
|
231
|
-
return
|
267
|
+
return Fp2.new(coeffs.map { |c| c * other }) if other.is_a?(Integer)
|
232
268
|
|
233
269
|
c0, c1 = coeffs
|
234
270
|
r0, r1 = other.coeffs
|
235
271
|
t1 = c0 * r0
|
236
272
|
t2 = c1 * r1
|
237
|
-
|
273
|
+
Fp2.new([t1 - t2, ((c0 + c1) * (r0 + r1)) - (t1 + t2)])
|
238
274
|
end
|
239
275
|
alias * multiply
|
240
276
|
|
241
277
|
def invert
|
242
278
|
a, b = values
|
243
|
-
factor =
|
244
|
-
|
279
|
+
factor = Fp.new(a * a + b * b).invert
|
280
|
+
Fp2.new([factor * a, factor * -b])
|
245
281
|
end
|
246
282
|
|
247
283
|
# Raises to q**i -th power
|
248
284
|
def frobenius_map(power)
|
249
|
-
|
285
|
+
Fp2.new([coeffs[0], coeffs[1] * Fp2::FROBENIUS_COEFFICIENTS[power % 2]])
|
250
286
|
end
|
251
287
|
|
252
288
|
def mul_by_non_residue
|
253
289
|
c0, c1 = coeffs
|
254
|
-
|
290
|
+
Fp2.new([c0 - c1, c0 + c1])
|
255
291
|
end
|
256
292
|
|
257
293
|
def multiply_by_b
|
258
294
|
c0, c1 = coeffs
|
259
295
|
t0 = c0 * 4
|
260
296
|
t1 = c1 * 4
|
261
|
-
|
297
|
+
Fp2.new([t0 - t1, t0 + t1])
|
262
298
|
end
|
263
299
|
end
|
264
300
|
|
265
301
|
# Finite extension field over irreducible polynomial.
|
266
|
-
#
|
267
|
-
class
|
302
|
+
# Fp2(v) / (v^3 - ξ) where ξ = u + 1
|
303
|
+
class Fp6
|
268
304
|
include FQP
|
269
305
|
|
270
306
|
attr_reader :coeffs
|
@@ -276,61 +312,61 @@ module BLS
|
|
276
312
|
end
|
277
313
|
|
278
314
|
def self.from_tuple(t)
|
279
|
-
|
315
|
+
Fp6.new([Fp2.new(t[0...2]), Fp2.new(t[2...4]), Fp2.new(t[4...6])])
|
280
316
|
end
|
281
317
|
|
282
|
-
ZERO =
|
283
|
-
ONE =
|
318
|
+
ZERO = Fp6.new([Fp2::ZERO, Fp2::ZERO, Fp2::ZERO])
|
319
|
+
ONE = Fp6.new([Fp2::ONE, Fp2::ZERO, Fp2::ZERO])
|
284
320
|
|
285
321
|
FROBENIUS_COEFFICIENTS_1 = [
|
286
|
-
|
322
|
+
Fp2.new([
|
287
323
|
0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001,
|
288
324
|
0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
289
325
|
]),
|
290
|
-
|
326
|
+
Fp2.new([
|
291
327
|
0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000,
|
292
328
|
0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaac
|
293
329
|
]),
|
294
|
-
|
330
|
+
Fp2.new([
|
295
331
|
0x00000000000000005f19672fdf76ce51ba69c6076a0f77eaddb3a93be6f89688de17d813620a00022e01fffffffefffe,
|
296
332
|
0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000,
|
297
333
|
]),
|
298
|
-
|
334
|
+
Fp2.new([
|
299
335
|
0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000,
|
300
336
|
0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001
|
301
337
|
]),
|
302
|
-
|
338
|
+
Fp2.new([
|
303
339
|
0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaac,
|
304
340
|
0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
305
341
|
]),
|
306
|
-
|
342
|
+
Fp2.new([
|
307
343
|
0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000,
|
308
344
|
0x00000000000000005f19672fdf76ce51ba69c6076a0f77eaddb3a93be6f89688de17d813620a00022e01fffffffefffe
|
309
345
|
])
|
310
346
|
].freeze
|
311
347
|
|
312
348
|
FROBENIUS_COEFFICIENTS_2 = [
|
313
|
-
|
349
|
+
Fp2.new([
|
314
350
|
0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001,
|
315
351
|
0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
316
352
|
]),
|
317
|
-
|
353
|
+
Fp2.new([
|
318
354
|
0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaad,
|
319
355
|
0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
320
356
|
]),
|
321
|
-
|
357
|
+
Fp2.new([
|
322
358
|
0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaac,
|
323
359
|
0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
324
360
|
]),
|
325
|
-
|
361
|
+
Fp2.new([
|
326
362
|
0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaaa,
|
327
363
|
0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
328
364
|
]),
|
329
|
-
|
365
|
+
Fp2.new([
|
330
366
|
0x00000000000000005f19672fdf76ce51ba69c6076a0f77eaddb3a93be6f89688de17d813620a00022e01fffffffefffe,
|
331
367
|
0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
332
368
|
]),
|
333
|
-
|
369
|
+
Fp2.new([
|
334
370
|
0x00000000000000005f19672fdf76ce51ba69c6076a0f77eaddb3a93be6f89688de17d813620a00022e01fffffffeffff,
|
335
371
|
0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
336
372
|
])
|
@@ -338,11 +374,11 @@ module BLS
|
|
338
374
|
|
339
375
|
# Multiply by quadratic non-residue v.
|
340
376
|
def mul_by_non_residue
|
341
|
-
|
377
|
+
Fp6.new([coeffs[2].mul_by_non_residue, coeffs[0], coeffs[1]])
|
342
378
|
end
|
343
379
|
|
344
380
|
def multiply(other)
|
345
|
-
return
|
381
|
+
return Fp6.new([coeffs[0] * other, coeffs[1] * other, coeffs[2] * other]) if other.is_a?(Integer)
|
346
382
|
|
347
383
|
c0, c1, c2 = coeffs
|
348
384
|
r0, r1, r2 = other.coeffs
|
@@ -350,7 +386,7 @@ module BLS
|
|
350
386
|
t1 = c1 * r1
|
351
387
|
t2 = c2 * r2
|
352
388
|
|
353
|
-
|
389
|
+
Fp6.new([
|
354
390
|
t0 + ((c1 + c2) * (r1 + r2) - (t1 + t2)).mul_by_non_residue,
|
355
391
|
(c0 + c1) * (r0 + r1) - (t0 + t1) + t2.mul_by_non_residue,
|
356
392
|
t1 + ((c0 + c2) * (r0 + r2) - (t0 + t2))
|
@@ -360,7 +396,7 @@ module BLS
|
|
360
396
|
|
361
397
|
# Sparse multiplication.
|
362
398
|
def multiply_by_1(b1)
|
363
|
-
|
399
|
+
Fp6.new([coeffs[2].multiply(b1).mul_by_non_residue, coeffs[0] * b1, coeffs[1] * b1])
|
364
400
|
end
|
365
401
|
|
366
402
|
# Sparse multiplication.
|
@@ -368,11 +404,11 @@ module BLS
|
|
368
404
|
c0, c1, c2 = coeffs
|
369
405
|
t0 = c0 * b0
|
370
406
|
t1 = c1 * b1
|
371
|
-
|
407
|
+
Fp6.new([((c1 + c2) * b1 - t1).mul_by_non_residue + t0, (b0 + b1) * (c0 + c1) - t0 - t1, (c0 + c2) * b0 - t0 + t1])
|
372
408
|
end
|
373
409
|
|
374
|
-
def
|
375
|
-
|
410
|
+
def multiply_by_fp2(other)
|
411
|
+
Fp6.new(coeffs.map { |c| c * other })
|
376
412
|
end
|
377
413
|
|
378
414
|
def square
|
@@ -381,7 +417,7 @@ module BLS
|
|
381
417
|
t1 = c0 * c1 * 2
|
382
418
|
t3 = c1 * c2 * 2
|
383
419
|
t4 = c2.square
|
384
|
-
|
420
|
+
Fp6.new([t3.mul_by_non_residue + t0, t4.mul_by_non_residue + t1, t1 + (c0 - c1 + c2).square + t3 - t0 - t4])
|
385
421
|
end
|
386
422
|
|
387
423
|
def invert
|
@@ -390,21 +426,21 @@ module BLS
|
|
390
426
|
t1 = c2.square.mul_by_non_residue - (c0 * c1)
|
391
427
|
t2 = c1.square - c0 * c2
|
392
428
|
t4 = ((c2 * t1 + c1 * t2).mul_by_non_residue + c0 * t0).invert
|
393
|
-
|
429
|
+
Fp6.new([t4 * t0, t4 * t1, t4 * t2])
|
394
430
|
end
|
395
431
|
|
396
432
|
def frobenius_map(power)
|
397
|
-
|
433
|
+
Fp6.new([
|
398
434
|
coeffs[0].frobenius_map(power),
|
399
|
-
coeffs[1].frobenius_map(power) *
|
400
|
-
coeffs[2].frobenius_map(power) *
|
435
|
+
coeffs[1].frobenius_map(power) * Fp6::FROBENIUS_COEFFICIENTS_1[power % 6],
|
436
|
+
coeffs[2].frobenius_map(power) * Fp6::FROBENIUS_COEFFICIENTS_2[power % 6]
|
401
437
|
])
|
402
438
|
end
|
403
439
|
end
|
404
440
|
|
405
441
|
# Finite extension field over irreducible polynomial.
|
406
|
-
#
|
407
|
-
class
|
442
|
+
# Fp6(w) / (w2 - γ) where γ = v
|
443
|
+
class Fp12
|
408
444
|
include FQP
|
409
445
|
|
410
446
|
attr_reader :coeffs
|
@@ -416,71 +452,71 @@ module BLS
|
|
416
452
|
end
|
417
453
|
|
418
454
|
def self.from_tuple(t)
|
419
|
-
|
455
|
+
Fp12.new([Fp6.from_tuple(t[0...6]), Fp6.from_tuple(t[6...12])])
|
420
456
|
end
|
421
457
|
|
422
|
-
ZERO =
|
423
|
-
ONE =
|
458
|
+
ZERO = Fp12.new([Fp6::ZERO, Fp6::ZERO])
|
459
|
+
ONE = Fp12.new([Fp6::ONE, Fp6::ZERO])
|
424
460
|
|
425
461
|
FROBENIUS_COEFFICIENTS = [
|
426
|
-
|
462
|
+
Fp2.new([
|
427
463
|
0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001,
|
428
464
|
0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
429
465
|
]),
|
430
|
-
|
466
|
+
Fp2.new([
|
431
467
|
0x1904d3bf02bb0667c231beb4202c0d1f0fd603fd3cbd5f4f7b2443d784bab9c4f67ea53d63e7813d8d0775ed92235fb8,
|
432
468
|
0x00fc3e2b36c4e03288e9e902231f9fb854a14787b6c7b36fec0c8ec971f63c5f282d5ac14d6c7ec22cf78a126ddc4af3
|
433
469
|
]),
|
434
|
-
|
470
|
+
Fp2.new([
|
435
471
|
0x00000000000000005f19672fdf76ce51ba69c6076a0f77eaddb3a93be6f89688de17d813620a00022e01fffffffeffff,
|
436
472
|
0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
437
473
|
]),
|
438
|
-
|
474
|
+
Fp2.new([
|
439
475
|
0x135203e60180a68ee2e9c448d77a2cd91c3dedd930b1cf60ef396489f61eb45e304466cf3e67fa0af1ee7b04121bdea2,
|
440
476
|
0x06af0e0437ff400b6831e36d6bd17ffe48395dabc2d3435e77f76e17009241c5ee67992f72ec05f4c81084fbede3cc09
|
441
477
|
]),
|
442
|
-
|
478
|
+
Fp2.new([
|
443
479
|
0x00000000000000005f19672fdf76ce51ba69c6076a0f77eaddb3a93be6f89688de17d813620a00022e01fffffffefffe,
|
444
480
|
0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
445
481
|
]),
|
446
|
-
|
482
|
+
Fp2.new([
|
447
483
|
0x144e4211384586c16bd3ad4afa99cc9170df3560e77982d0db45f3536814f0bd5871c1908bd478cd1ee605167ff82995,
|
448
484
|
0x05b2cfd9013a5fd8df47fa6b48b1e045f39816240c0b8fee8beadf4d8e9c0566c63a3e6e257f87329b18fae980078116
|
449
485
|
]),
|
450
|
-
|
486
|
+
Fp2.new([
|
451
487
|
0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaaa,
|
452
488
|
0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
453
489
|
]),
|
454
|
-
|
490
|
+
Fp2.new([
|
455
491
|
0x00fc3e2b36c4e03288e9e902231f9fb854a14787b6c7b36fec0c8ec971f63c5f282d5ac14d6c7ec22cf78a126ddc4af3,
|
456
492
|
0x1904d3bf02bb0667c231beb4202c0d1f0fd603fd3cbd5f4f7b2443d784bab9c4f67ea53d63e7813d8d0775ed92235fb8
|
457
493
|
]),
|
458
|
-
|
494
|
+
Fp2.new([
|
459
495
|
0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaac,
|
460
496
|
0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
461
497
|
]),
|
462
|
-
|
498
|
+
Fp2.new([
|
463
499
|
0x06af0e0437ff400b6831e36d6bd17ffe48395dabc2d3435e77f76e17009241c5ee67992f72ec05f4c81084fbede3cc09,
|
464
500
|
0x135203e60180a68ee2e9c448d77a2cd91c3dedd930b1cf60ef396489f61eb45e304466cf3e67fa0af1ee7b04121bdea2
|
465
501
|
]),
|
466
|
-
|
502
|
+
Fp2.new([
|
467
503
|
0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaad,
|
468
504
|
0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
469
505
|
]),
|
470
|
-
|
506
|
+
Fp2.new([
|
471
507
|
0x05b2cfd9013a5fd8df47fa6b48b1e045f39816240c0b8fee8beadf4d8e9c0566c63a3e6e257f87329b18fae980078116,
|
472
508
|
0x144e4211384586c16bd3ad4afa99cc9170df3560e77982d0db45f3536814f0bd5871c1908bd478cd1ee605167ff82995
|
473
509
|
])
|
474
510
|
].freeze
|
475
511
|
|
476
512
|
def multiply(other)
|
477
|
-
return
|
513
|
+
return Fp12.new([coeffs[0] * other, coeffs[1] * other]) if other.is_a?(Integer)
|
478
514
|
|
479
515
|
c0, c1 = coeffs
|
480
516
|
r0, r1 = other.coeffs
|
481
517
|
t1 = c0 * r0
|
482
518
|
t2 = c1 * r1
|
483
|
-
|
519
|
+
Fp12.new([t1 + t2.mul_by_non_residue, (c0 + c1) * (r0 + r1) - (t1 + t2)])
|
484
520
|
end
|
485
521
|
alias * multiply
|
486
522
|
|
@@ -488,35 +524,35 @@ module BLS
|
|
488
524
|
c0, c1 = coeffs
|
489
525
|
t0 = c0.multiply_by_01(o0, o1)
|
490
526
|
t1 = c1.multiply_by_1(o4)
|
491
|
-
|
527
|
+
Fp12.new([t1.mul_by_non_residue + t0, (c1 + c0).multiply_by_01(o0, o1 + o4) - t0 - t1])
|
492
528
|
end
|
493
529
|
|
494
|
-
def
|
495
|
-
|
530
|
+
def multiply_by_fp2(other)
|
531
|
+
Fp12.new(coeffs.map{ |c| c.multiply_by_fp2(other) })
|
496
532
|
end
|
497
533
|
|
498
534
|
def square
|
499
535
|
c0, c1 = coeffs
|
500
536
|
ab = c0 * c1
|
501
|
-
|
537
|
+
Fp12.new([(c1.mul_by_non_residue + c0) * (c0 + c1) - ab - ab.mul_by_non_residue, ab + ab])
|
502
538
|
end
|
503
539
|
|
504
540
|
def invert
|
505
541
|
c0, c1 = coeffs
|
506
542
|
t = (c0.square - c1.square.mul_by_non_residue).invert
|
507
|
-
|
543
|
+
Fp12.new([c0 * t, (c1 * t).negate])
|
508
544
|
end
|
509
545
|
|
510
546
|
def frobenius_map(power)
|
511
547
|
c0, c1 = coeffs
|
512
548
|
r0 = c0.frobenius_map(power)
|
513
549
|
c1_0, c1_1, c1_2 = c1.frobenius_map(power).coeffs
|
514
|
-
|
550
|
+
Fp12.new([
|
515
551
|
r0,
|
516
|
-
|
517
|
-
c1_0 *
|
518
|
-
c1_1 *
|
519
|
-
c1_2 *
|
552
|
+
Fp6.new([
|
553
|
+
c1_0 * Fp12::FROBENIUS_COEFFICIENTS[power % 12],
|
554
|
+
c1_1 * Fp12::FROBENIUS_COEFFICIENTS[power % 12],
|
555
|
+
c1_2 * Fp12::FROBENIUS_COEFFICIENTS[power % 12]])])
|
520
556
|
end
|
521
557
|
|
522
558
|
def final_exponentiate
|
@@ -535,17 +571,17 @@ module BLS
|
|
535
571
|
c0, c1 = coeffs
|
536
572
|
c0c0, c0c1, c0c2 = c0.coeffs
|
537
573
|
c1c0, c1c1, c1c2 = c1.coeffs
|
538
|
-
t3, t4 =
|
539
|
-
t5, t6 =
|
540
|
-
t7, t8 =
|
574
|
+
t3, t4 = fp4_square(c0c0, c1c1)
|
575
|
+
t5, t6 = fp4_square(c1c0, c0c2)
|
576
|
+
t7, t8 = fp4_square(c0c1, c1c2)
|
541
577
|
t9 = t8.mul_by_non_residue
|
542
|
-
|
543
|
-
|
544
|
-
|
578
|
+
Fp12.new([
|
579
|
+
Fp6.new([(t3 - c0c0) * 2 + t3, (t5 - c0c1) * 2 + t5, (t7 - c0c2) * 2 + t7]),
|
580
|
+
Fp6.new([(t9 + c1c0) * 2 + t9, (t4 + c1c1) * 2 + t4, (t6 + c1c2) * 2 + t6])])
|
545
581
|
end
|
546
582
|
|
547
583
|
def cyclotomic_exp(n)
|
548
|
-
z =
|
584
|
+
z = Fp12::ONE
|
549
585
|
i = BLS_X_LEN - 1
|
550
586
|
while i >= 0
|
551
587
|
z = z.cyclotomic_square
|
@@ -557,10 +593,10 @@ module BLS
|
|
557
593
|
|
558
594
|
private
|
559
595
|
|
560
|
-
# @param [
|
561
|
-
# @param [
|
596
|
+
# @param [Fp2] a
|
597
|
+
# @param [Fp2] b
|
562
598
|
# @return [Array]
|
563
|
-
def
|
599
|
+
def fp4_square(a, b)
|
564
600
|
a2 = a.square
|
565
601
|
b2 = b.square
|
566
602
|
[b2.mul_by_non_residue + a2, (a + b).square - a2 - b2]
|
@@ -568,10 +604,10 @@ module BLS
|
|
568
604
|
|
569
605
|
end
|
570
606
|
|
571
|
-
UT_ROOT = BLS::
|
572
|
-
WSQ = BLS::
|
607
|
+
UT_ROOT = BLS::Fp6.new([BLS::Fp2::ZERO, BLS::Fp2::ONE, BLS::Fp2::ZERO])
|
608
|
+
WSQ = BLS::Fp12.new([UT_ROOT, BLS::Fp6::ZERO])
|
573
609
|
WSQ_INV = WSQ.invert
|
574
|
-
WCU = BLS::
|
610
|
+
WCU = BLS::Fp12.new([BLS::Fp6::ZERO, UT_ROOT])
|
575
611
|
WCU_INV = WCU.invert
|
576
612
|
# 1 / F2(2)^((p - 1) / 3) in GF(p^2)
|
577
613
|
PSI2_C1 = 0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaac
|
@@ -580,54 +616,54 @@ module BLS
|
|
580
616
|
P_MINUS_9_DIV_16 = (Curve::P**2 - 9) / 16
|
581
617
|
|
582
618
|
XNUM = [
|
583
|
-
|
619
|
+
Fp2.new([
|
584
620
|
0x5c759507e8e333ebb5b7a9a47d7ed8532c52d39fd3a042a88b58423c50ae15d5c2638e343d9c71c6238aaaaaaaa97d6,
|
585
621
|
0x5c759507e8e333ebb5b7a9a47d7ed8532c52d39fd3a042a88b58423c50ae15d5c2638e343d9c71c6238aaaaaaaa97d6]),
|
586
|
-
|
622
|
+
Fp2.new([
|
587
623
|
0x0,
|
588
624
|
0x11560bf17baa99bc32126fced787c88f984f87adf7ae0c7f9a208c6b4f20a4181472aaa9cb8d555526a9ffffffffc71a]),
|
589
|
-
|
625
|
+
Fp2.new([
|
590
626
|
0x11560bf17baa99bc32126fced787c88f984f87adf7ae0c7f9a208c6b4f20a4181472aaa9cb8d555526a9ffffffffc71e,
|
591
627
|
0x8ab05f8bdd54cde190937e76bc3e447cc27c3d6fbd7063fcd104635a790520c0a395554e5c6aaaa9354ffffffffe38d]),
|
592
|
-
|
628
|
+
Fp2.new([
|
593
629
|
0x171d6541fa38ccfaed6dea691f5fb614cb14b4e7f4e810aa22d6108f142b85757098e38d0f671c7188e2aaaaaaaa5ed1,
|
594
630
|
0x0])
|
595
631
|
].freeze
|
596
632
|
XDEN = [
|
597
|
-
|
633
|
+
Fp2.new([
|
598
634
|
0x0,
|
599
635
|
0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaa63]),
|
600
|
-
|
636
|
+
Fp2.new([
|
601
637
|
0xc,
|
602
638
|
0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaa9f]),
|
603
|
-
|
604
|
-
|
639
|
+
Fp2::ONE,
|
640
|
+
Fp2::ZERO
|
605
641
|
].freeze
|
606
642
|
YNUM = [
|
607
|
-
|
643
|
+
Fp2.new([
|
608
644
|
0x1530477c7ab4113b59a4c18b076d11930f7da5d4a07f649bf54439d87d27e500fc8c25ebf8c92f6812cfc71c71c6d706,
|
609
645
|
0x1530477c7ab4113b59a4c18b076d11930f7da5d4a07f649bf54439d87d27e500fc8c25ebf8c92f6812cfc71c71c6d706]),
|
610
|
-
|
646
|
+
Fp2.new([
|
611
647
|
0x0,
|
612
648
|
0x5c759507e8e333ebb5b7a9a47d7ed8532c52d39fd3a042a88b58423c50ae15d5c2638e343d9c71c6238aaaaaaaa97be]),
|
613
|
-
|
649
|
+
Fp2.new([
|
614
650
|
0x11560bf17baa99bc32126fced787c88f984f87adf7ae0c7f9a208c6b4f20a4181472aaa9cb8d555526a9ffffffffc71c,
|
615
651
|
0x8ab05f8bdd54cde190937e76bc3e447cc27c3d6fbd7063fcd104635a790520c0a395554e5c6aaaa9354ffffffffe38f]),
|
616
|
-
|
652
|
+
Fp2.new([
|
617
653
|
0x124c9ad43b6cf79bfbf7043de3811ad0761b0f37a1e26286b0e977c69aa274524e79097a56dc4bd9e1b371c71c718b10,
|
618
654
|
0x0])
|
619
655
|
].freeze
|
620
656
|
YDEN = [
|
621
|
-
|
657
|
+
Fp2.new([
|
622
658
|
0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffa8fb,
|
623
659
|
0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffa8fb]),
|
624
|
-
|
660
|
+
Fp2.new([
|
625
661
|
0x0,
|
626
662
|
0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffa9d3]),
|
627
|
-
|
663
|
+
Fp2.new([
|
628
664
|
0x12,
|
629
665
|
0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaa99]),
|
630
|
-
|
666
|
+
Fp2.new([0x1, 0x0])
|
631
667
|
].freeze
|
632
668
|
|
633
669
|
ISOGENY_COEFFICIENTS = [XNUM, XDEN, YNUM, YDEN]
|
@@ -635,8 +671,8 @@ module BLS
|
|
635
671
|
module_function
|
636
672
|
|
637
673
|
def psi(x, y)
|
638
|
-
x2 = WSQ_INV.
|
639
|
-
y2 = WCU_INV.
|
674
|
+
x2 = WSQ_INV.multiply_by_fp2(x).frobenius_map(1).multiply(WSQ).coeffs[0].coeffs[0]
|
675
|
+
y2 = WCU_INV.multiply_by_fp2(y).frobenius_map(1).multiply(WCU).coeffs[0].coeffs[0]
|
640
676
|
[x2, y2]
|
641
677
|
end
|
642
678
|
|
@@ -645,7 +681,7 @@ module BLS
|
|
645
681
|
end
|
646
682
|
|
647
683
|
def miller_loop(ell, g1)
|
648
|
-
f12 =
|
684
|
+
f12 = Fp12::ONE
|
649
685
|
p_x, p_y = g1
|
650
686
|
i = BLS_X_LEN - 2
|
651
687
|
j = 0
|
@@ -672,13 +708,13 @@ module BLS
|
|
672
708
|
sign_0 || (zero_0 && sign_1)
|
673
709
|
end
|
674
710
|
|
675
|
-
def
|
711
|
+
def sqrt_div_fp2(u, v)
|
676
712
|
uv7 = u * v**7
|
677
713
|
uv15 = uv7 * v**8
|
678
714
|
gamma = uv15**P_MINUS_9_DIV_16 * uv7
|
679
715
|
success = false
|
680
716
|
result = gamma
|
681
|
-
positive_roots_of_unity =
|
717
|
+
positive_roots_of_unity = Fp2::ROOTS_OF_UNITY[0...4]
|
682
718
|
positive_roots_of_unity.each do |root|
|
683
719
|
candidate = root * gamma
|
684
720
|
if (candidate**2 * v - u).zero? && !success
|