Coverage Report

Created: 2025-04-24 07:09

/src/blst_optimize_size/src/aggregate.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright Supranational LLC
3
 * Licensed under the Apache License, Version 2.0, see LICENSE for details.
4
 * SPDX-License-Identifier: Apache-2.0
5
 */
6
7
/*
8
 * Usage pattern on single-processor system is
9
 *
10
 * blst_pairing_init(ctx, hash_or_encode, DST);
11
 * blst_pairing_aggregate_pk_in_g1(ctx, PK[0], aggregated_signature, msg[0]);
12
 * blst_pairing_aggregate_pk_in_g1(ctx, PK[1], NULL, msg[1]);
13
 * ...
14
 * blst_pairing_commit(ctx);
15
 * blst_pairing_finalverify(ctx, NULL);
16
 *
17
 ***********************************************************************
18
 * Usage pattern on multi-processor system is
19
 *
20
 *   blst_pairing_init(pk[0], hash_or_encode, DST);
21
 *   blst_pairing_init(pk[1], hash_or_encode, DST);
22
 *   ...
23
 * start threads each processing an N/nthreads slice of PKs and messages:
24
 *     blst_pairing_aggregate_pk_in_g1(pk[i], PK[i*n+0], NULL, msg[i*n+0]);
25
 *     blst_pairing_aggregate_pk_in_g1(pk[i], PK[i*n+1], NULL, msg[i*n+1]);
26
 *     ...
27
 *     blst_pairing_commit(pkx);
28
 *   ...
29
 * meanwhile in main thread
30
 *   blst_fp12 gtsig;
31
 *   blst_aggregated_in_g2(&gtsig, aggregated_signature);
32
 * join threads and merge their contexts:
33
 *   blst_pairing_merge(pk[0], pk[1]);
34
 *   blst_pairing_merge(pk[0], pk[2]);
35
 *   ...
36
 *   blst_pairing_finalverify(pk[0], gtsig);
37
 */
38
39
#ifndef N_MAX
40
669
# define N_MAX 8
41
#endif
42
43
typedef union { POINTonE1 e1; POINTonE2 e2; } AggregatedSignature;
44
typedef struct {
45
    unsigned int ctrl;
46
    unsigned int nelems;
47
    const void *DST;
48
    size_t DST_len;
49
    vec384fp12 GT;
50
    AggregatedSignature AggrSign;
51
    POINTonE2_affine Q[N_MAX];
52
    POINTonE1_affine P[N_MAX];
53
} PAIRING;
54
55
enum { AGGR_UNDEFINED      = 0,
56
       AGGR_MIN_SIG        = 1,
57
       AGGR_MIN_PK         = 2,
58
       AGGR_SIGN_SET       = 0x10,
59
       AGGR_GT_SET         = 0x20,
60
       AGGR_HASH_OR_ENCODE = 0x40 };
61
643
#define MIN_SIG_OR_PK (AGGR_MIN_SIG | AGGR_MIN_PK)
62
63
static const size_t sizeof_pairing = (sizeof(PAIRING) + 7) & ~(size_t)7;
64
65
size_t blst_pairing_sizeof(void)
66
0
{   return sizeof_pairing;   }
67
68
void blst_pairing_init(PAIRING *ctx, int hash_or_encode,
69
                       const void *DST, size_t DST_len)
70
0
{
71
0
    ctx->ctrl = AGGR_UNDEFINED | (hash_or_encode ? AGGR_HASH_OR_ENCODE : 0);
72
0
    ctx->nelems = 0;
73
0
    ctx->DST = (uptr_t)DST==(uptr_t)((byte *)ctx+sizeof_pairing) ? (void *)42
74
0
                                                                 : DST;
75
0
    ctx->DST_len = DST_len;
76
0
}
77
78
static const void *pairing_get_dst(const PAIRING *ctx)
79
750
{   return (uptr_t)ctx->DST==(uptr_t)42 ? (const byte *)ctx+sizeof_pairing
80
750
                                        : ctx->DST;
81
750
}
82
83
const void *blst_pairing_get_dst(const PAIRING *ctx)
84
0
{   return pairing_get_dst(ctx);   }
85
86
1.37k
#define FROM_AFFINE(out,in) do { \
87
1.37k
    vec_copy((out)->X, in->X, 2*sizeof(in->X)), \
88
1.37k
    vec_select((out)->Z, in->X, BLS12_381_Rx.p, sizeof(in->X), \
89
1.37k
                         vec_is_zero(in->X, 2*sizeof(in->X))); } while(0)
90
91
/*
92
 * Optional |nbits|-wide |scalar| is used to facilitate multiple aggregated
93
 * signature verification as discussed at
94
 * https://ethresear.ch/t/fast-verification-of-multiple-bls-signatures/5407.
95
 * Usage pattern is not finalized yet, because (sig != NULL) is better and
96
 * will be handled separately...
97
 */
98
static BLST_ERROR PAIRING_Aggregate_PK_in_G2(PAIRING *ctx,
99
                                             const POINTonE2_affine *PK,
100
                                             size_t pk_groupcheck,
101
                                             const POINTonE1_affine *sig,
102
                                             size_t sig_groupcheck,
103
                                             const byte *scalar, size_t nbits,
104
                                             const void *msg, size_t msg_len,
105
                                             const void *aug, size_t aug_len)
106
0
{
107
0
    if (ctx->ctrl & AGGR_MIN_PK)
108
0
        return BLST_AGGR_TYPE_MISMATCH;
109
110
0
    ctx->ctrl |= AGGR_MIN_SIG;
111
112
    /*
113
     * Since we don't know if the signature is individual or aggregated,
114
     * the only sensible thing to do is to skip over infinite one and
115
     * count on the corresponding infinite public key to be rejected,
116
     * in case the signature is non-aggregated that is.
117
     */
118
0
    if (sig != NULL && !vec_is_zero(sig, sizeof(*sig))) {
119
0
        POINTonE1 *S = &ctx->AggrSign.e1;
120
0
        POINTonE1 P[1];
121
122
0
        FROM_AFFINE(P, sig);
123
124
0
        if (sig_groupcheck && !POINTonE1_in_G1(P))
125
0
            return BLST_POINT_NOT_IN_GROUP;
126
127
0
        if (ctx->ctrl & AGGR_SIGN_SET) {
128
0
            if (nbits != 0 && scalar != NULL) {
129
0
                POINTonE1_mult_w5(P, P, scalar, nbits);
130
0
                POINTonE1_dadd(S, S, P, NULL);
131
0
            } else {
132
0
                POINTonE1_dadd_affine(S, S, sig);
133
0
            }
134
0
        } else {
135
0
            ctx->ctrl |= AGGR_SIGN_SET;
136
0
            if (nbits != 0 && scalar != NULL)
137
0
                POINTonE1_mult_w5(S, P, scalar, nbits);
138
0
            else
139
0
                vec_copy(S, P, sizeof(P));
140
0
        }
141
0
    }
142
143
0
    if (PK != NULL) {
144
0
        unsigned int n;
145
0
        POINTonE1 H[1];
146
0
        const void *DST = pairing_get_dst(ctx);
147
148
        /*
149
         * Reject infinite public keys.
150
         */
151
0
        if (vec_is_zero(PK, sizeof(*PK)))
152
0
            return BLST_PK_IS_INFINITY;
153
154
0
        if (pk_groupcheck) {
155
0
            POINTonE2 P[1];
156
157
0
            FROM_AFFINE(P, PK);
158
0
            if (!POINTonE2_in_G2(P))
159
0
                return BLST_POINT_NOT_IN_GROUP;
160
0
        }
161
162
0
        if (ctx->ctrl & AGGR_HASH_OR_ENCODE)
163
0
            Hash_to_G1(H, msg, msg_len, DST, ctx->DST_len, aug, aug_len);
164
0
        else
165
0
            Encode_to_G1(H, msg, msg_len, DST, ctx->DST_len, aug, aug_len);
166
167
0
        if (nbits != 0 && scalar != NULL)
168
0
            POINTonE1_mult_w5(H, H, scalar, nbits);
169
170
0
        POINTonE1_from_Jacobian(H, H);
171
172
0
        n = ctx->nelems;
173
0
        vec_copy(ctx->Q + n, PK, sizeof(POINTonE2_affine));
174
0
        vec_copy(ctx->P + n, H, sizeof(POINTonE1_affine));
175
0
        if (++n == N_MAX) {
176
0
            if (ctx->ctrl & AGGR_GT_SET) {
177
0
                vec384fp12 GT;
178
0
                miller_loop_n(GT, ctx->Q, ctx->P, n);
179
0
                mul_fp12(ctx->GT, ctx->GT, GT);
180
0
            } else {
181
0
                miller_loop_n(ctx->GT, ctx->Q, ctx->P, n);
182
0
                ctx->ctrl |= AGGR_GT_SET;
183
0
            }
184
0
            n = 0;
185
0
        }
186
0
        ctx->nelems = n;
187
0
    }
188
189
0
    return BLST_SUCCESS;
190
0
}
191
192
BLST_ERROR blst_pairing_aggregate_pk_in_g2(PAIRING *ctx,
193
                                           const POINTonE2_affine *PK,
194
                                           const POINTonE1_affine *signature,
195
                                           const void *msg, size_t msg_len,
196
                                           const void *aug, size_t aug_len)
197
0
{   return PAIRING_Aggregate_PK_in_G2(ctx, PK, 0, signature, 1, NULL, 0,
198
0
                                      msg, msg_len, aug, aug_len);
199
0
}
200
201
BLST_ERROR blst_pairing_mul_n_aggregate_pk_in_g2(PAIRING *ctx,
202
                                                 const POINTonE2_affine *PK,
203
                                                 const POINTonE1_affine *sig,
204
                                                 const byte *scalar,
205
                                                 size_t nbits,
206
                                                 const void *msg,
207
                                                 size_t msg_len,
208
                                                 const void *aug,
209
                                                 size_t aug_len)
210
0
{   return PAIRING_Aggregate_PK_in_G2(ctx, PK, 0, sig, 1, scalar, nbits,
211
0
                                      msg, msg_len, aug, aug_len);
212
0
}
213
214
BLST_ERROR blst_pairing_chk_n_aggr_pk_in_g2(PAIRING *ctx,
215
                                            const POINTonE2_affine *PK,
216
                                            size_t pk_grpchk,
217
                                            const POINTonE1_affine *signature,
218
                                            size_t sig_grpchk,
219
                                            const void *msg, size_t msg_len,
220
                                            const void *aug, size_t aug_len)
221
0
{   return PAIRING_Aggregate_PK_in_G2(ctx, PK, pk_grpchk, signature, sig_grpchk,
222
0
                                      NULL, 0, msg, msg_len, aug, aug_len);
223
0
}
224
225
BLST_ERROR blst_pairing_chk_n_mul_n_aggr_pk_in_g2(PAIRING *ctx,
226
                                                  const POINTonE2_affine *PK,
227
                                                  size_t pk_grpchk,
228
                                                  const POINTonE1_affine *sig,
229
                                                  size_t sig_grpchk,
230
                                                  const byte *scalar,
231
                                                  size_t nbits,
232
                                                  const void *msg,
233
                                                  size_t msg_len,
234
                                                  const void *aug,
235
                                                  size_t aug_len)
236
0
{   return PAIRING_Aggregate_PK_in_G2(ctx, PK, pk_grpchk, sig, sig_grpchk,
237
0
                                      scalar, nbits,
238
0
                                      msg, msg_len, aug, aug_len);
239
0
}
240
241
static BLST_ERROR PAIRING_Aggregate_PK_in_G1(PAIRING *ctx,
242
                                             const POINTonE1_affine *PK,
243
                                             size_t pk_groupcheck,
244
                                             const POINTonE2_affine *sig,
245
                                             size_t sig_groupcheck,
246
                                             const byte *scalar, size_t nbits,
247
                                             const void *msg, size_t msg_len,
248
                                             const void *aug, size_t aug_len)
249
783
{
250
783
    if (ctx->ctrl & AGGR_MIN_SIG)
251
0
        return BLST_AGGR_TYPE_MISMATCH;
252
253
783
    ctx->ctrl |= AGGR_MIN_PK;
254
255
    /*
256
     * Since we don't know if the signature is individual or aggregated,
257
     * the only sensible thing to do is to skip over infinite one and
258
     * count on the corresponding infinite public key to be rejected,
259
     * in case the signature is non-aggregated that is.
260
     */
261
783
    if (sig != NULL && !vec_is_zero(sig, sizeof(*sig))) {
262
677
        POINTonE2 *S = &ctx->AggrSign.e2;
263
677
        POINTonE2 P[1];
264
265
677
        FROM_AFFINE(P, sig);
266
267
677
        if (sig_groupcheck && !POINTonE2_in_G2(P))
268
33
            return BLST_POINT_NOT_IN_GROUP;
269
270
644
        if (ctx->ctrl & AGGR_SIGN_SET) {
271
0
            if (nbits != 0 && scalar != NULL) {
272
273
0
                POINTonE2_mult_w5(P, P, scalar, nbits);
274
0
                POINTonE2_dadd(S, S, P, NULL);
275
0
            } else {
276
0
                POINTonE2_dadd_affine(S, S, sig);
277
0
            }
278
644
        } else {
279
644
            ctx->ctrl |= AGGR_SIGN_SET;
280
644
            if (nbits != 0 && scalar != NULL)
281
0
                POINTonE2_mult_w5(S, P, scalar, nbits);
282
644
            else
283
644
                vec_copy(S, P, sizeof(P));
284
644
        }
285
644
    }
286
287
750
    if (PK != NULL) {
288
750
        unsigned int n;
289
750
        POINTonE2 H[1];
290
750
        POINTonE1 pk[1];
291
750
        const void *DST = pairing_get_dst(ctx);
292
293
        /*
294
         * Reject infinite public keys.
295
         */
296
750
        if (vec_is_zero(PK, sizeof(*PK)))
297
51
            return BLST_PK_IS_INFINITY;
298
299
699
        if (pk_groupcheck) {
300
699
            POINTonE1 P[1];
301
302
699
            FROM_AFFINE(P, PK);
303
699
            if (!POINTonE1_in_G1(P))
304
30
                return BLST_POINT_NOT_IN_GROUP;
305
699
        }
306
307
669
        if (ctx->ctrl & AGGR_HASH_OR_ENCODE)
308
669
            Hash_to_G2(H, msg, msg_len, DST, ctx->DST_len, aug, aug_len);
309
0
        else
310
0
            Encode_to_G2(H, msg, msg_len, DST, ctx->DST_len, aug, aug_len);
311
312
669
        POINTonE2_from_Jacobian(H, H);
313
314
669
        if (nbits != 0 && scalar != NULL) {
315
0
            FROM_AFFINE(pk, PK);
316
0
            POINTonE1_mult_w5(pk, pk, scalar, nbits);
317
0
            POINTonE1_from_Jacobian(pk, pk);
318
0
            PK = (const POINTonE1_affine *)pk;
319
0
        }
320
321
669
        n = ctx->nelems;
322
669
        vec_copy(ctx->Q + n, H, sizeof(POINTonE2_affine));
323
669
        vec_copy(ctx->P + n, PK, sizeof(POINTonE1_affine));
324
669
        if (++n == N_MAX) {
325
0
            if (ctx->ctrl & AGGR_GT_SET) {
326
0
                vec384fp12 GT;
327
0
                miller_loop_n(GT, ctx->Q, ctx->P, n);
328
0
                mul_fp12(ctx->GT, ctx->GT, GT);
329
0
            } else {
330
0
                miller_loop_n(ctx->GT, ctx->Q, ctx->P, n);
331
0
                ctx->ctrl |= AGGR_GT_SET;
332
0
            }
333
0
            n = 0;
334
0
        }
335
669
        ctx->nelems = n;
336
669
    }
337
338
669
    return BLST_SUCCESS;
339
750
}
340
341
BLST_ERROR blst_pairing_aggregate_pk_in_g1(PAIRING *ctx,
342
                                           const POINTonE1_affine *PK,
343
                                           const POINTonE2_affine *signature,
344
                                           const void *msg, size_t msg_len,
345
                                           const void *aug, size_t aug_len)
346
0
{   return PAIRING_Aggregate_PK_in_G1(ctx, PK, 0, signature, 1, NULL, 0,
347
0
                                      msg, msg_len, aug, aug_len);
348
0
}
349
350
BLST_ERROR blst_pairing_mul_n_aggregate_pk_in_g1(PAIRING *ctx,
351
                                                 const POINTonE1_affine *PK,
352
                                                 const POINTonE2_affine *sig,
353
                                                 const byte *scalar,
354
                                                 size_t nbits,
355
                                                 const void *msg,
356
                                                 size_t msg_len,
357
                                                 const void *aug,
358
                                                 size_t aug_len)
359
0
{   return PAIRING_Aggregate_PK_in_G1(ctx, PK, 0, sig, 1, scalar, nbits,
360
0
                                      msg, msg_len, aug, aug_len);
361
0
}
362
363
BLST_ERROR blst_pairing_chk_n_aggr_pk_in_g1(PAIRING *ctx,
364
                                            const POINTonE1_affine *PK,
365
                                            size_t pk_grpchk,
366
                                            const POINTonE2_affine *signature,
367
                                            size_t sig_grpchk,
368
                                            const void *msg, size_t msg_len,
369
                                            const void *aug, size_t aug_len)
370
0
{   return PAIRING_Aggregate_PK_in_G1(ctx, PK, pk_grpchk, signature, sig_grpchk,
371
0
                                      NULL, 0, msg, msg_len, aug, aug_len);
372
0
}
373
374
BLST_ERROR blst_pairing_chk_n_mul_n_aggr_pk_in_g1(PAIRING *ctx,
375
                                                  const POINTonE1_affine *PK,
376
                                                  size_t pk_grpchk,
377
                                                  const POINTonE2_affine *sig,
378
                                                  size_t sig_grpchk,
379
                                                  const byte *scalar,
380
                                                  size_t nbits,
381
                                                  const void *msg,
382
                                                  size_t msg_len,
383
                                                  const void *aug,
384
                                                  size_t aug_len)
385
0
{   return PAIRING_Aggregate_PK_in_G1(ctx, PK, pk_grpchk, sig, sig_grpchk,
386
0
                                      scalar, nbits,
387
0
                                      msg, msg_len, aug, aug_len);
388
0
}
389
390
static void PAIRING_Commit(PAIRING *ctx)
391
669
{
392
669
    unsigned int n;
393
394
669
    if ((n = ctx->nelems) != 0) {
395
669
        if (ctx->ctrl & AGGR_GT_SET) {
396
0
            vec384fp12 GT;
397
0
            miller_loop_n(GT, ctx->Q, ctx->P, n);
398
0
            mul_fp12(ctx->GT, ctx->GT, GT);
399
669
        } else {
400
669
            miller_loop_n(ctx->GT, ctx->Q, ctx->P, n);
401
669
            ctx->ctrl |= AGGR_GT_SET;
402
669
        }
403
669
        ctx->nelems = 0;
404
669
    }
405
669
}
406
407
void blst_pairing_commit(PAIRING *ctx)
408
0
{   PAIRING_Commit(ctx);   }
409
410
BLST_ERROR blst_pairing_merge(PAIRING *ctx, const PAIRING *ctx1)
411
0
{
412
0
    if ((ctx->ctrl & MIN_SIG_OR_PK) != AGGR_UNDEFINED
413
0
        && (ctx1->ctrl & MIN_SIG_OR_PK) != AGGR_UNDEFINED
414
0
        && (ctx->ctrl & ctx1->ctrl & MIN_SIG_OR_PK) == 0)
415
0
        return BLST_AGGR_TYPE_MISMATCH;
416
417
    /* context producers are expected to have called blst_pairing_commit */
418
0
    if (ctx->nelems || ctx1->nelems)
419
0
        return BLST_AGGR_TYPE_MISMATCH;
420
421
0
    ctx->ctrl |= ctx1->ctrl & MIN_SIG_OR_PK;
422
423
0
    switch (ctx->ctrl & MIN_SIG_OR_PK) {
424
0
        case AGGR_MIN_SIG:
425
0
            if (ctx->ctrl & ctx1->ctrl & AGGR_SIGN_SET) {
426
0
                POINTonE1_dadd(&ctx->AggrSign.e1, &ctx->AggrSign.e1,
427
0
                                                  &ctx1->AggrSign.e1, NULL);
428
0
            } else if (ctx1->ctrl & AGGR_SIGN_SET) {
429
0
                ctx->ctrl |= AGGR_SIGN_SET;
430
0
                vec_copy(&ctx->AggrSign.e1, &ctx1->AggrSign.e1,
431
0
                         sizeof(ctx->AggrSign.e1));
432
0
            }
433
0
            break;
434
0
        case AGGR_MIN_PK:
435
0
            if (ctx->ctrl & ctx1->ctrl & AGGR_SIGN_SET) {
436
0
                POINTonE2_dadd(&ctx->AggrSign.e2, &ctx->AggrSign.e2,
437
0
                                                  &ctx1->AggrSign.e2, NULL);
438
0
            } else if (ctx1->ctrl & AGGR_SIGN_SET) {
439
0
                ctx->ctrl |= AGGR_SIGN_SET;
440
0
                vec_copy(&ctx->AggrSign.e2, &ctx1->AggrSign.e2,
441
0
                         sizeof(ctx->AggrSign.e2));
442
0
            }
443
0
            break;
444
0
        case AGGR_UNDEFINED:
445
0
            break;
446
0
        default:
447
0
            return BLST_AGGR_TYPE_MISMATCH;
448
0
    }
449
450
0
    if (ctx->ctrl & ctx1->ctrl & AGGR_GT_SET) {
451
0
        mul_fp12(ctx->GT, ctx->GT, ctx1->GT);
452
0
    } else if (ctx1->ctrl & AGGR_GT_SET) {
453
0
        ctx->ctrl |= AGGR_GT_SET;
454
0
        vec_copy(ctx->GT, ctx1->GT, sizeof(ctx->GT));
455
0
    }
456
457
0
    return BLST_SUCCESS;
458
0
}
459
460
static bool_t PAIRING_FinalVerify(const PAIRING *ctx, const vec384fp12 GTsig)
461
669
{
462
669
    vec384fp12 GT;
463
464
669
    if (!(ctx->ctrl & AGGR_GT_SET))
465
0
        return 0;
466
467
669
    if (GTsig != NULL) {
468
0
        vec_copy(GT, GTsig, sizeof(GT));
469
669
    } else if (ctx->ctrl & AGGR_SIGN_SET) {
470
643
        AggregatedSignature AggrSign;
471
472
643
        switch (ctx->ctrl & MIN_SIG_OR_PK) {
473
0
            case AGGR_MIN_SIG:
474
0
                POINTonE1_from_Jacobian(&AggrSign.e1, &ctx->AggrSign.e1);
475
0
                miller_loop_n(GT, (const POINTonE2_affine *)&BLS12_381_G2,
476
0
                                  (const POINTonE1_affine *)&AggrSign.e1, 1);
477
0
                break;
478
643
            case AGGR_MIN_PK:
479
643
                POINTonE2_from_Jacobian(&AggrSign.e2, &ctx->AggrSign.e2);
480
643
                miller_loop_n(GT, (const POINTonE2_affine *)&AggrSign.e2,
481
643
                                  (const POINTonE1_affine *)&BLS12_381_G1, 1);
482
643
                break;
483
0
            default:
484
0
                return 0;
485
643
        }
486
643
    } else {
487
        /*
488
         * The aggregated signature was infinite, relation between the
489
         * hashes and the public keys has to be VERY special...
490
         */
491
26
        vec_copy(GT, BLS12_381_Rx.p12, sizeof(GT));
492
26
    }
493
494
669
    conjugate_fp12(GT);
495
669
    mul_fp12(GT, GT, ctx->GT);
496
669
    final_exp(GT, GT);
497
498
    /* return GT==1 */
499
669
    return vec_is_equal(GT[0][0], BLS12_381_Rx.p2, sizeof(GT[0][0])) &
500
669
           vec_is_zero(GT[0][1], sizeof(GT) - sizeof(GT[0][0]));
501
669
}
502
503
int blst_pairing_finalverify(const PAIRING *ctx, const vec384fp12 GTsig)
504
0
{   return (int)PAIRING_FinalVerify(ctx, GTsig);   }
505
506
int blst_fp12_finalverify(const vec384fp12 GT1, const vec384fp12 GT2)
507
0
{
508
0
    vec384fp12 GT;
509
510
0
    vec_copy(GT, GT1, sizeof(GT));
511
0
    conjugate_fp12(GT);
512
0
    mul_fp12(GT, GT, GT2);
513
0
    final_exp(GT, GT);
514
515
    /* return GT==1 */
516
0
    return (int)(vec_is_equal(GT[0][0], BLS12_381_Rx.p2, sizeof(GT[0][0])) &
517
0
                 vec_is_zero(GT[0][1], sizeof(GT) - sizeof(GT[0][0])));
518
0
}
519
520
void blst_pairing_raw_aggregate(PAIRING *ctx, const POINTonE2_affine *q,
521
                                              const POINTonE1_affine *p)
522
0
{
523
0
    unsigned int n;
524
525
0
    if (vec_is_zero(q, sizeof(*q)) & vec_is_zero(p, sizeof(*p)))
526
0
        return;
527
528
0
    n = ctx->nelems;
529
0
    vec_copy(ctx->Q + n, q, sizeof(*q));
530
0
    vec_copy(ctx->P + n, p, sizeof(*p));
531
0
    if (++n == N_MAX) {
532
0
        if (ctx->ctrl & AGGR_GT_SET) {
533
0
            vec384fp12 GT;
534
0
            miller_loop_n(GT, ctx->Q, ctx->P, n);
535
0
            mul_fp12(ctx->GT, ctx->GT, GT);
536
0
        } else {
537
0
            miller_loop_n(ctx->GT, ctx->Q, ctx->P, n);
538
0
            ctx->ctrl |= AGGR_GT_SET;
539
0
        }
540
0
        n = 0;
541
0
    }
542
0
    ctx->nelems = n;
543
0
}
544
545
vec384fp12 *blst_pairing_as_fp12(PAIRING *ctx)
546
0
{
547
0
    PAIRING_Commit(ctx);
548
0
    return (vec384fp12 *)ctx->GT;
549
0
}
550
551
/*
552
 * PAIRING context-free entry points.
553
 *
554
 * To perform FastAggregateVerify, aggregate all public keys and
555
 * signatures with corresponding blst_aggregate_in_g{12}, convert
556
 * result to affine and call suitable blst_core_verify_pk_in_g{12}
557
 * or blst_aggregated_in_g{12}...
558
 */
559
BLST_ERROR blst_aggregate_in_g1(POINTonE1 *out, const POINTonE1 *in,
560
                                                const unsigned char *zwire)
561
2.47k
{
562
2.47k
    POINTonE1 P[1];
563
2.47k
    BLST_ERROR ret;
564
565
2.47k
    ret = POINTonE1_Deserialize_Z((POINTonE1_affine *)P, zwire);
566
567
2.47k
    if (ret != BLST_SUCCESS)
568
52
        return ret;
569
570
2.42k
    if (vec_is_zero(P, sizeof(POINTonE1_affine))) {
571
2.42k
        if (in == NULL)
572
148
            vec_zero(out, sizeof(*out));
573
2.42k
        return BLST_SUCCESS;
574
2.42k
    }
575
576
0
    vec_copy(P->Z, BLS12_381_Rx.p, sizeof(P->Z));
577
578
0
    if (!POINTonE1_in_G1(P))
579
0
        return BLST_POINT_NOT_IN_GROUP;
580
581
0
    if (in == NULL)
582
0
        vec_copy(out, P, sizeof(P));
583
0
    else
584
0
        POINTonE1_dadd_affine(out, in, (POINTonE1_affine *)P);
585
586
0
    return BLST_SUCCESS;
587
0
}
588
589
BLST_ERROR blst_aggregate_in_g2(POINTonE2 *out, const POINTonE2 *in,
590
                                                const unsigned char *zwire)
591
1.98k
{
592
1.98k
    POINTonE2 P[1];
593
1.98k
    BLST_ERROR ret;
594
595
1.98k
    ret = POINTonE2_Deserialize_Z((POINTonE2_affine *)P, zwire);
596
597
1.98k
    if (ret != BLST_SUCCESS)
598
61
        return ret;
599
600
1.92k
    if (vec_is_zero(P, sizeof(POINTonE2_affine))) {
601
1.92k
        if (in == NULL)
602
187
            vec_zero(out, sizeof(*out));
603
1.92k
        return BLST_SUCCESS;
604
1.92k
    }
605
606
0
    vec_copy(P->Z, BLS12_381_Rx.p, sizeof(P->Z));
607
608
0
    if (!POINTonE2_in_G2(P))
609
0
        return BLST_POINT_NOT_IN_GROUP;
610
611
0
    if (in == NULL) {
612
0
        vec_copy(out, P, sizeof(P));
613
0
    } else {
614
0
        POINTonE2_dadd_affine(out, in, (POINTonE2_affine *)P);
615
0
    }
616
0
    return BLST_SUCCESS;
617
0
}
618
619
void blst_aggregated_in_g1(vec384fp12 ret, const POINTonE1_affine *sig)
620
0
{   miller_loop_n(ret, (const POINTonE2_affine *)&BLS12_381_G2, sig, 1);   }
621
622
void blst_aggregated_in_g2(vec384fp12 ret, const POINTonE2_affine *sig)
623
0
{   miller_loop_n(ret, sig, (const POINTonE1_affine *)&BLS12_381_G1, 1);   }
624
625
BLST_ERROR blst_core_verify_pk_in_g1(const POINTonE1_affine *pk,
626
                                     const POINTonE2_affine *signature,
627
                                     int hash_or_encode,
628
                                     const void *msg, size_t msg_len,
629
                                     const void *DST, size_t DST_len,
630
                                     const void *aug, size_t aug_len)
631
783
{
632
783
    PAIRING ctx;
633
783
    BLST_ERROR ret;
634
635
783
    ctx.ctrl = AGGR_UNDEFINED | (hash_or_encode ? AGGR_HASH_OR_ENCODE : 0);
636
783
    ctx.nelems = 0;
637
783
    ctx.DST = DST;
638
783
    ctx.DST_len = DST_len;
639
640
783
    ret = PAIRING_Aggregate_PK_in_G1(&ctx, pk, 1, signature, 1, NULL, 0,
641
783
                                     msg, msg_len, aug, aug_len);
642
783
    if (ret != BLST_SUCCESS)
643
114
        return ret;
644
645
669
    PAIRING_Commit(&ctx);
646
647
669
    return PAIRING_FinalVerify(&ctx, NULL) ? BLST_SUCCESS : BLST_VERIFY_FAIL;
648
783
}
649
650
BLST_ERROR blst_core_verify_pk_in_g2(const POINTonE2_affine *pk,
651
                                     const POINTonE1_affine *signature,
652
                                     int hash_or_encode,
653
                                     const void *msg, size_t msg_len,
654
                                     const void *DST, size_t DST_len,
655
                                     const void *aug, size_t aug_len)
656
0
{
657
0
    PAIRING ctx;
658
0
    BLST_ERROR ret;
659
660
0
    ctx.ctrl = AGGR_UNDEFINED | (hash_or_encode ? AGGR_HASH_OR_ENCODE : 0);
661
0
    ctx.nelems = 0;
662
0
    ctx.DST = DST;
663
0
    ctx.DST_len = DST_len;
664
665
0
    ret = PAIRING_Aggregate_PK_in_G2(&ctx, pk, 1, signature, 1, NULL, 0,
666
0
                                     msg, msg_len, aug, aug_len);
667
0
    if (ret != BLST_SUCCESS)
668
0
        return ret;
669
670
0
    PAIRING_Commit(&ctx);
671
672
0
    return PAIRING_FinalVerify(&ctx, NULL) ? BLST_SUCCESS : BLST_VERIFY_FAIL;
673
0
}