Coverage Report

Created: 2026-11-12 06:54

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/blst/src/exports.c
Line
Count
Source
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
 * Why this file? Overall goal is to ensure that all internal calls
8
 * remain internal after linking application. This is to both
9
 *
10
 * a) minimize possibility of external name conflicts (since all
11
 *    non-blst-prefixed and [assembly subroutines] remain static);
12
 * b) preclude possibility of unintentional internal reference
13
 *    overload in shared library context (one can achieve same
14
 *    effect with -Bsymbolic, but we don't want to rely on end-user
15
 *    to remember to use it);
16
 */
17
18
#include "fields.h"
19
#include "bytes.h"
20
21
/*
22
 * BLS12-381-specific Fr shortcuts to assembly.
23
 */
24
void blst_fr_add(vec256 ret, const vec256 a, const vec256 b)
25
21
{   add_mod_256(ret, a, b, BLS12_381_r);   }
26
27
void blst_fr_sub(vec256 ret, const vec256 a, const vec256 b)
28
142
{   sub_mod_256(ret, a, b, BLS12_381_r);   }
29
30
void blst_fr_mul_by_3(vec256 ret, const vec256 a)
31
3
{   mul_by_3_mod_256(ret, a, BLS12_381_r);   }
32
33
void blst_fr_lshift(vec256 ret, const vec256 a, size_t count)
34
23
{   lshift_mod_256(ret, a, count, BLS12_381_r);   }
35
36
void blst_fr_rshift(vec256 ret, const vec256 a, size_t count)
37
130
{   rshift_mod_256(ret, a, count, BLS12_381_r);   }
38
39
void blst_fr_mul(vec256 ret, const vec256 a, const vec256 b)
40
91
{   mul_mont_sparse_256(ret, a, b, BLS12_381_r, r0);   }
41
42
void blst_fr_ct_bfly(vec256 x0, vec256 x1, const vec256 twiddle)
43
0
{
44
0
    vec256 x2;
45
46
0
    mul_mont_sparse_256(x2, x1, twiddle, BLS12_381_r, r0);
47
0
    sub_mod_256(x1, x0, x2, BLS12_381_r);
48
0
    add_mod_256(x0, x0, x2, BLS12_381_r);
49
0
}
50
51
void blst_fr_gs_bfly(vec256 x0, vec256 x1, const vec256 twiddle)
52
0
{
53
0
    vec256 x2;
54
55
0
    sub_mod_256(x2, x0, x1, BLS12_381_r);
56
0
    add_mod_256(x0, x0, x1, BLS12_381_r);
57
0
    mul_mont_sparse_256(x1, x2, twiddle, BLS12_381_r, r0);
58
0
}
59
60
void blst_fr_sqr(vec256 ret, const vec256 a)
61
38
{   sqr_mont_sparse_256(ret, a, BLS12_381_r, r0);   }
62
63
void blst_fr_cneg(vec256 ret, const vec256 a, int flag)
64
8
{   cneg_mod_256(ret, a, is_zero(flag) ^ 1, BLS12_381_r);   }
65
66
void blst_fr_to(vec256 ret, const vec256 a)
67
0
{   mul_mont_sparse_256(ret, BLS12_381_rRR, a, BLS12_381_r, r0);   }
68
69
void blst_fr_from(vec256 ret, const vec256 a)
70
0
{   from_mont_256(ret, a, BLS12_381_r, r0);   }
71
72
void blst_fr_from_scalar(vec256 ret, const pow256 a)
73
0
{
74
0
    const union {
75
0
        long one;
76
0
        char little;
77
0
    } is_endian = { 1 };
78
79
0
    if ((uptr_t)ret == (uptr_t)a && is_endian.little) {
80
0
        mul_mont_sparse_256(ret, BLS12_381_rRR, (const limb_t *)a,
81
0
                                 BLS12_381_r, r0);
82
0
    } else {
83
0
        vec256 out;
84
0
        limbs_from_le_bytes(out, a, 32);
85
0
        mul_mont_sparse_256(ret, BLS12_381_rRR, out, BLS12_381_r, r0);
86
0
        vec_zero(out, sizeof(out));
87
0
    }
88
0
}
89
90
void blst_scalar_from_fr(pow256 ret, const vec256 a)
91
0
{
92
0
    const union {
93
0
        long one;
94
0
        char little;
95
0
    } is_endian = { 1 };
96
97
0
    if ((uptr_t)ret == (uptr_t)a && is_endian.little) {
98
0
        from_mont_256((limb_t *)ret, a, BLS12_381_r, r0);
99
0
    } else {
100
0
        vec256 out;
101
0
        from_mont_256(out, a, BLS12_381_r, r0);
102
0
        le_bytes_from_limbs(ret, out, 32);
103
0
        vec_zero(out, sizeof(out));
104
0
    }
105
0
}
106
107
int blst_scalar_fr_check(const pow256 a)
108
0
{   return (int)(check_mod_256(a, BLS12_381_r) |
109
0
                 bytes_are_zero(a, sizeof(pow256)));
110
0
}
111
112
int blst_sk_check(const pow256 a)
113
336
{   return (int)check_mod_256(a, BLS12_381_r);   }
114
115
int blst_sk_add_n_check(pow256 ret, const pow256 a, const pow256 b)
116
0
{   return (int)add_n_check_mod_256(ret, a, b, BLS12_381_r);   }
117
118
int blst_sk_sub_n_check(pow256 ret, const pow256 a, const pow256 b)
119
0
{   return (int)sub_n_check_mod_256(ret, a, b, BLS12_381_r);   }
120
121
int blst_sk_mul_n_check(pow256 ret, const pow256 a, const pow256 b)
122
0
{
123
0
    vec256 t[2];
124
0
    const union {
125
0
        long one;
126
0
        char little;
127
0
    } is_endian = { 1 };
128
0
    bool_t is_zero;
129
130
0
    if (((size_t)a|(size_t)b)%sizeof(limb_t) != 0 || !is_endian.little) {
131
0
        limbs_from_le_bytes(t[0], a, sizeof(pow256));
132
0
        limbs_from_le_bytes(t[1], b, sizeof(pow256));
133
0
        a = (const byte *)t[0];
134
0
        b = (const byte *)t[1];
135
0
    }
136
0
    mul_mont_sparse_256(t[0], BLS12_381_rRR, (const limb_t *)a, BLS12_381_r, r0);
137
0
    mul_mont_sparse_256(t[0], t[0], (const limb_t *)b, BLS12_381_r, r0);
138
0
    le_bytes_from_limbs(ret, t[0], sizeof(pow256));
139
0
    is_zero = vec_is_zero(t[0], sizeof(vec256));
140
0
    vec_zero(t, sizeof(t));
141
142
0
    return (int)(is_zero^1);
143
0
}
144
145
void blst_sk_inverse(pow256 ret, const pow256 a)
146
0
{
147
0
    const union {
148
0
        long one;
149
0
        char little;
150
0
    } is_endian = { 1 };
151
152
0
    if (((size_t)a|(size_t)ret)%sizeof(limb_t) == 0 && is_endian.little) {
153
0
        limb_t *out = (limb_t *)ret;
154
0
        mul_mont_sparse_256(out, BLS12_381_rRR, (const limb_t *)a,
155
0
                                 BLS12_381_r, r0);
156
0
        reciprocal_fr(out, out);
157
0
        from_mont_256(out, out, BLS12_381_r, r0);
158
0
    } else {
159
0
        vec256 out;
160
0
        limbs_from_le_bytes(out, a, 32);
161
0
        mul_mont_sparse_256(out, BLS12_381_rRR, out, BLS12_381_r, r0);
162
0
        reciprocal_fr(out, out);
163
0
        from_mont_256(out, out, BLS12_381_r, r0);
164
0
        le_bytes_from_limbs(ret, out, 32);
165
0
        vec_zero(out, sizeof(out));
166
0
    }
167
0
}
168
169
/*
170
 * BLS12-381-specific Fp shortcuts to assembly.
171
 */
172
void blst_fp_add(vec384 ret, const vec384 a, const vec384 b)
173
7
{   add_fp(ret, a, b);   }
174
175
void blst_fp_sub(vec384 ret, const vec384 a, const vec384 b)
176
28
{   sub_fp(ret, a, b);   }
177
178
void blst_fp_mul_by_3(vec384 ret, const vec384 a)
179
3
{   mul_by_3_fp(ret, a);   }
180
181
void blst_fp_mul_by_8(vec384 ret, const vec384 a)
182
4
{   mul_by_8_fp(ret, a);   }
183
184
void blst_fp_lshift(vec384 ret, const vec384 a, size_t count)
185
20
{   lshift_fp(ret, a, count);   }
186
187
void blst_fp_mul(vec384 ret, const vec384 a, const vec384 b)
188
210
{   mul_fp(ret, a, b);   }
189
190
void blst_fp_sqr(vec384 ret, const vec384 a)
191
209
{   sqr_fp(ret, a);   }
192
193
void blst_fp_cneg(vec384 ret, const vec384 a, int flag)
194
112
{   cneg_fp(ret, a, is_zero(flag) ^ 1);   }
195
196
void blst_fp_to(vec384 ret, const vec384 a)
197
0
{   mul_fp(ret, a, BLS12_381_RR);   }
198
199
void blst_fp_from(vec384 ret, const vec384 a)
200
0
{   from_fp(ret, a);   }
201
202
/*
203
 * Fp serialization/deserialization.
204
 */
205
void blst_fp_from_uint32(vec384 ret, const unsigned int a[12])
206
0
{
207
0
    if (sizeof(limb_t) == 8) {
208
0
        int i;
209
0
        for (i = 0; i < 6; i++)
210
0
            ret[i] = a[2*i] | ((limb_t)a[2*i+1] << (32 & (8*sizeof(limb_t)-1)));
211
0
        a = (const unsigned int *)ret;
212
0
    }
213
0
    mul_fp(ret, (const limb_t *)a, BLS12_381_RR);
214
0
}
215
216
void blst_uint32_from_fp(unsigned int ret[12], const vec384 a)
217
0
{
218
0
    if (sizeof(limb_t) == 4) {
219
0
        from_fp((limb_t *)ret, a);
220
0
    } else {
221
0
        vec384 out;
222
0
        int i;
223
224
0
        from_fp(out, a);
225
0
        for (i = 0; i < 6; i++) {
226
0
            limb_t limb = out[i];
227
0
            ret[2*i]   = (unsigned int)limb;
228
0
            ret[2*i+1] = (unsigned int)(limb >> (32 & (8*sizeof(limb_t)-1)));
229
0
        }
230
0
    }
231
0
}
232
233
void blst_fp_from_uint64(vec384 ret, const unsigned long long a[6])
234
9.23k
{
235
9.23k
    const union {
236
9.23k
        long one;
237
9.23k
        char little;
238
9.23k
    } is_endian = { 1 };
239
240
9.23k
    if (sizeof(limb_t) == 4 && !is_endian.little) {
241
0
        int i;
242
0
        for (i = 0; i < 6; i++) {
243
0
            unsigned long long limb = a[i];
244
0
            ret[2*i]   = (limb_t)limb;
245
0
            ret[2*i+1] = (limb_t)(limb >> 32);
246
0
        }
247
0
        a = (const unsigned long long *)ret;
248
0
    }
249
9.23k
    mul_fp(ret, (const limb_t *)a, BLS12_381_RR);
250
9.23k
}
251
252
void blst_uint64_from_fp(unsigned long long ret[6], const vec384 a)
253
5.17k
{
254
5.17k
    const union {
255
5.17k
        long one;
256
5.17k
        char little;
257
5.17k
    } is_endian = { 1 };
258
259
5.17k
    if (sizeof(limb_t) == 8 || is_endian.little) {
260
5.17k
        from_fp((limb_t *)ret, a);
261
5.17k
    } else {
262
0
        vec384 out;
263
0
        int i;
264
265
0
        from_fp(out, a);
266
0
        for (i = 0; i < 6; i++)
267
0
            ret[i] = out[2*i] | ((unsigned long long)out[2*i+1] << 32);
268
0
    }
269
5.17k
}
270
271
void blst_fp_from_bendian(vec384 ret, const unsigned char a[48])
272
0
{
273
0
    vec384 out;
274
275
0
    limbs_from_be_bytes(out, a, sizeof(vec384));
276
0
    mul_fp(ret, out, BLS12_381_RR);
277
0
}
278
279
void blst_bendian_from_fp(unsigned char ret[48], const vec384 a)
280
0
{
281
0
    vec384 out;
282
283
0
    from_fp(out, a);
284
0
    be_bytes_from_limbs(ret, out, sizeof(vec384));
285
0
}
286
287
void blst_fp_from_lendian(vec384 ret, const unsigned char a[48])
288
0
{
289
0
    vec384 out;
290
291
0
    limbs_from_le_bytes(out, a, sizeof(vec384));
292
0
    mul_fp(ret, out, BLS12_381_RR);
293
0
}
294
295
void blst_lendian_from_fp(unsigned char ret[48], const vec384 a)
296
0
{
297
0
    vec384 out;
298
299
0
    from_fp(out, a);
300
0
    le_bytes_from_limbs(ret, out, sizeof(vec384));
301
0
}
302
303
/*
304
 * BLS12-381-specific Fp2 shortcuts to assembly.
305
 */
306
void blst_fp2_add(vec384x ret, const vec384x a, const vec384x b)
307
0
{   add_fp2(ret, a, b);   }
308
309
void blst_fp2_sub(vec384x ret, const vec384x a, const vec384x b)
310
0
{   sub_fp2(ret, a, b);   }
311
312
void blst_fp2_mul_by_3(vec384x ret, const vec384x a)
313
0
{   mul_by_3_fp2(ret, a);   }
314
315
void blst_fp2_mul_by_8(vec384x ret, const vec384x a)
316
0
{   mul_by_8_fp2(ret, a);   }
317
318
void blst_fp2_lshift(vec384x ret, const vec384x a, size_t count)
319
0
{   lshift_fp2(ret, a, count);    }
320
321
void blst_fp2_mul(vec384x ret, const vec384x a, const vec384x b)
322
0
{   mul_fp2(ret, a, b);   }
323
324
void blst_fp2_sqr(vec384x ret, const vec384x a)
325
0
{   sqr_fp2(ret, a);   }
326
327
void blst_fp2_cneg(vec384x ret, const vec384x a, int flag)
328
0
{   cneg_fp2(ret, a, is_zero(flag) ^ 1);   }
329
330
/*
331
 * Scalar serialization/deserialization.
332
 */
333
void blst_scalar_from_uint32(pow256 ret, const unsigned int a[8])
334
0
{
335
0
    const union {
336
0
        long one;
337
0
        char little;
338
0
    } is_endian = { 1 };
339
0
    size_t i;
340
341
0
    if ((uptr_t)ret==(uptr_t)a && is_endian.little)
342
0
        return;
343
344
0
    for(i = 0; i < 8; i++) {
345
0
        unsigned int w = a[i];
346
0
        *ret++ = (byte)w;
347
0
        *ret++ = (byte)(w >> 8);
348
0
        *ret++ = (byte)(w >> 16);
349
0
        *ret++ = (byte)(w >> 24);
350
0
    }
351
0
}
352
353
void blst_uint32_from_scalar(unsigned int ret[8], const pow256 a)
354
0
{
355
0
    const union {
356
0
        long one;
357
0
        char little;
358
0
    } is_endian = { 1 };
359
0
    size_t i;
360
361
0
    if ((uptr_t)ret==(uptr_t)a && is_endian.little)
362
0
        return;
363
364
0
    for(i = 0; i < 8; i++) {
365
0
        unsigned int w = (unsigned int)(*a++);
366
0
        w |= (unsigned int)(*a++) << 8;
367
0
        w |= (unsigned int)(*a++) << 16;
368
0
        w |= (unsigned int)(*a++) << 24;
369
0
        ret[i] = w;
370
0
    }
371
0
}
372
373
void blst_scalar_from_uint64(pow256 ret, const unsigned long long a[4])
374
336
{
375
336
    const union {
376
336
        long one;
377
336
        char little;
378
336
    } is_endian = { 1 };
379
336
    size_t i;
380
381
336
    if ((uptr_t)ret==(uptr_t)a && is_endian.little)
382
0
        return;
383
384
1.68k
    for(i = 0; i < 4; i++) {
385
1.34k
        unsigned long long w = a[i];
386
1.34k
        *ret++ = (byte)w;
387
1.34k
        *ret++ = (byte)(w >> 8);
388
1.34k
        *ret++ = (byte)(w >> 16);
389
1.34k
        *ret++ = (byte)(w >> 24);
390
1.34k
        *ret++ = (byte)(w >> 32);
391
1.34k
        *ret++ = (byte)(w >> 40);
392
1.34k
        *ret++ = (byte)(w >> 48);
393
1.34k
        *ret++ = (byte)(w >> 56);
394
1.34k
    }
395
336
}
396
397
void blst_uint64_from_scalar(unsigned long long ret[4], const pow256 a)
398
0
{
399
0
    const union {
400
0
        long one;
401
0
        char little;
402
0
    } is_endian = { 1 };
403
0
    size_t i;
404
405
0
    if ((uptr_t)ret==(uptr_t)a && is_endian.little)
406
0
        return;
407
408
0
    for(i = 0; i < 4; i++) {
409
0
        unsigned long long w = (unsigned long long)(*a++);
410
0
        w |= (unsigned long long)(*a++) << 8;
411
0
        w |= (unsigned long long)(*a++) << 16;
412
0
        w |= (unsigned long long)(*a++) << 24;
413
0
        w |= (unsigned long long)(*a++) << 32;
414
0
        w |= (unsigned long long)(*a++) << 40;
415
0
        w |= (unsigned long long)(*a++) << 48;
416
0
        w |= (unsigned long long)(*a++) << 56;
417
0
        ret[i] = w;
418
0
    }
419
0
}
420
421
void blst_scalar_from_bendian(pow256 ret, const unsigned char a[32])
422
0
{
423
0
    vec256 out;
424
0
    limbs_from_be_bytes(out, a, sizeof(out));
425
0
    le_bytes_from_limbs(ret, out, sizeof(out));
426
0
    vec_zero(out, sizeof(out));
427
0
}
428
429
void blst_bendian_from_scalar(unsigned char ret[32], const pow256 a)
430
0
{
431
0
    vec256 out;
432
0
    limbs_from_le_bytes(out, a, sizeof(out));
433
0
    be_bytes_from_limbs(ret, out, sizeof(out));
434
0
    vec_zero(out, sizeof(out));
435
0
}
436
437
void blst_scalar_from_lendian(pow256 ret, const unsigned char a[32])
438
0
{
439
0
    size_t i;
440
441
0
    if ((uptr_t)ret==(uptr_t)a)
442
0
        return;
443
444
0
    for (i = 0; i < 32; i++)
445
0
        ret[i] = a[i];
446
0
}
447
448
void blst_lendian_from_scalar(unsigned char ret[32], const pow256 a)
449
0
{
450
0
    size_t i;
451
452
0
    if ((uptr_t)ret==(uptr_t)a)
453
0
        return;
454
455
0
    for (i = 0; i < 32; i++)
456
0
        ret[i] = a[i];
457
0
}
458
459
void blst_fr_from_uint64(vec256 ret, const unsigned long long a[4])
460
1.50k
{
461
1.50k
    const union {
462
1.50k
        long one;
463
1.50k
        char little;
464
1.50k
    } is_endian = { 1 };
465
466
1.50k
    if (sizeof(limb_t) == 4 && !is_endian.little) {
467
0
        int i;
468
0
        for (i = 0; i < 4; i++) {
469
0
            unsigned long long limb = a[i];
470
0
            ret[2*i]   = (limb_t)limb;
471
0
            ret[2*i+1] = (limb_t)(limb >> 32);
472
0
        }
473
0
        a = (const unsigned long long *)ret;
474
0
    }
475
1.50k
    mul_mont_sparse_256(ret, BLS12_381_rRR, (const limb_t *)a, BLS12_381_r, r0);
476
1.50k
}
477
478
void blst_uint64_from_fr(unsigned long long ret[4], const vec256 a)
479
360
{
480
360
    const union {
481
360
        long one;
482
360
        char little;
483
360
    } is_endian = { 1 };
484
485
360
    if (sizeof(limb_t) == 8 || is_endian.little) {
486
360
        from_mont_256((limb_t *)ret, a, BLS12_381_r, r0);
487
360
    } else {
488
0
        vec256 out;
489
0
        int i;
490
491
0
        from_mont_256(out, a, BLS12_381_r, r0);
492
0
        for (i = 0; i < 4; i++)
493
0
            ret[i] = out[2*i] | ((unsigned long long)out[2*i+1] << 32);
494
0
        vec_zero(out, sizeof(out));
495
0
    }
496
360
}
497
498
int blst_scalar_from_le_bytes(pow256 out, const unsigned char *bytes, size_t n)
499
0
{
500
0
    size_t rem = n ? ((n - 1) % 32 + 1) : 0;
501
0
    struct { vec256 out, digit; } t;
502
0
    limb_t ret;
503
504
0
    vec_zero(t.out, sizeof(t.out));
505
506
0
    n -= rem;
507
0
    limbs_from_le_bytes(t.out, bytes += n, rem);
508
0
    mul_mont_sparse_256(t.out, BLS12_381_rRR, t.out, BLS12_381_r, r0);
509
510
0
    while (n) {
511
0
        limbs_from_le_bytes(t.digit, bytes -= 32, 32);
512
0
        add_mod_256(t.out, t.out, t.digit, BLS12_381_r);
513
0
        mul_mont_sparse_256(t.out, BLS12_381_rRR, t.out, BLS12_381_r, r0);
514
0
        n -= 32;
515
0
    }
516
517
0
    from_mont_256(t.out, t.out, BLS12_381_r, r0);
518
519
0
    ret = vec_is_zero(t.out, sizeof(t.out));
520
0
    le_bytes_from_limbs(out, t.out, 32);
521
0
    vec_zero(&t, sizeof(t));
522
523
0
    return (int)(ret^1);
524
0
}
525
526
int blst_scalar_from_be_bytes(pow256 out, const unsigned char *bytes, size_t n)
527
0
{
528
0
    size_t rem = n ? ((n - 1) % 32 + 1) : 0;
529
0
    struct { vec256 out, digit; } t;
530
0
    limb_t ret;
531
532
0
    vec_zero(t.out, sizeof(t.out));
533
534
0
    limbs_from_be_bytes(t.out, bytes, rem);
535
0
    mul_mont_sparse_256(t.out, BLS12_381_rRR, t.out, BLS12_381_r, r0);
536
537
0
    while (n -= rem) {
538
0
        limbs_from_be_bytes(t.digit, bytes += rem, 32);
539
0
        add_mod_256(t.out, t.out, t.digit, BLS12_381_r);
540
0
        mul_mont_sparse_256(t.out, BLS12_381_rRR, t.out, BLS12_381_r, r0);
541
0
        rem = 32;
542
0
    }
543
544
0
    from_mont_256(t.out, t.out, BLS12_381_r, r0);
545
546
0
    ret = vec_is_zero(t.out, sizeof(t.out));
547
0
    le_bytes_from_limbs(out, t.out, 32);
548
0
    vec_zero(&t, sizeof(t));
549
550
0
    return (int)(ret^1);
551
0
}
552
553
void blst_fp_from_le_bytes(vec384 out, const unsigned char *bytes, size_t n)
554
0
{
555
0
    size_t rem = n ? ((n - 1) % 48 + 1) : 0;
556
0
    vec384 digit;
557
558
0
    vec_zero(out, sizeof(vec384));
559
560
0
    n -= rem;
561
0
    limbs_from_le_bytes(out, bytes += n, rem);
562
0
    mul_mont_384(out, BLS12_381_RR, out, BLS12_381_P, p0);
563
564
0
    while (n) {
565
0
        limbs_from_le_bytes(digit, bytes -= 48, 48);
566
0
        add_mod_384(out, out, digit, BLS12_381_P);
567
0
        mul_mont_384(out, BLS12_381_RR, out, BLS12_381_P, p0);
568
0
        n -= 48;
569
0
    }
570
0
}
571
572
void blst_fp_from_be_bytes(vec384 out, const unsigned char *bytes, size_t n)
573
0
{
574
0
    size_t rem = n ? ((n - 1) % 48 + 1) : 0;
575
0
    vec384 digit;
576
577
0
    vec_zero(out, sizeof(vec384));
578
579
0
    limbs_from_be_bytes(out, bytes, rem);
580
0
    mul_mont_384(out, BLS12_381_RR, out, BLS12_381_P, p0);
581
582
0
    while (n -= rem) {
583
0
        limbs_from_be_bytes(digit, bytes += rem, 48);
584
0
        add_mod_384(out, out, digit, BLS12_381_P);
585
0
        mul_mont_384(out, BLS12_381_RR, out, BLS12_381_P, p0);
586
0
        rem = 48;
587
0
    }
588
0
}
589
590
/*
591
 * Single-short SHA-256 hash function.
592
 */
593
#include "sha256.h"
594
595
void blst_sha256(unsigned char md[32], const void *msg, size_t len)
596
0
{
597
0
    SHA256_CTX ctx;
598
599
0
    sha256_init(&ctx);
600
0
    sha256_update(&ctx, msg, len);
601
0
    sha256_final(md, &ctx);
602
0
}
603
604
/*
605
 * Test facilitator.
606
 */
607
void blst_scalar_from_hexascii(pow256 ret, const char *hex)
608
0
{   bytes_from_hexascii(ret, sizeof(pow256), hex);   }
609
610
void blst_fr_from_hexascii(vec256 ret, const char *hex)
611
0
{
612
0
    limbs_from_hexascii(ret, sizeof(vec256), hex);
613
0
    mul_mont_sparse_256(ret, BLS12_381_rRR, ret, BLS12_381_r, r0);
614
0
}
615
616
void blst_fp_from_hexascii(vec384 ret, const char *hex)
617
0
{
618
0
    limbs_from_hexascii(ret, sizeof(vec384), hex);
619
0
    mul_fp(ret, ret, BLS12_381_RR);
620
0
}