4 static uint64_t load_3(const unsigned char *in
) {
7 result
= (uint64_t) in
[0];
8 result
|= ((uint64_t) in
[1]) << 8;
9 result
|= ((uint64_t) in
[2]) << 16;
14 static uint64_t load_4(const unsigned char *in
) {
17 result
= (uint64_t) in
[0];
18 result
|= ((uint64_t) in
[1]) << 8;
19 result
|= ((uint64_t) in
[2]) << 16;
20 result
|= ((uint64_t) in
[3]) << 24;
27 s[0]+256*s[1]+...+256^63*s[63] = s
30 s[0]+256*s[1]+...+256^31*s[31] = s mod l
31 where l = 2^252 + 27742317777372353535851937790883648493.
32 Overwrites s in place.
35 void sc_reduce(unsigned char *s
) {
36 int64_t s0
= 2097151 & load_3(s
);
37 int64_t s1
= 2097151 & (load_4(s
+ 2) >> 5);
38 int64_t s2
= 2097151 & (load_3(s
+ 5) >> 2);
39 int64_t s3
= 2097151 & (load_4(s
+ 7) >> 7);
40 int64_t s4
= 2097151 & (load_4(s
+ 10) >> 4);
41 int64_t s5
= 2097151 & (load_3(s
+ 13) >> 1);
42 int64_t s6
= 2097151 & (load_4(s
+ 15) >> 6);
43 int64_t s7
= 2097151 & (load_3(s
+ 18) >> 3);
44 int64_t s8
= 2097151 & load_3(s
+ 21);
45 int64_t s9
= 2097151 & (load_4(s
+ 23) >> 5);
46 int64_t s10
= 2097151 & (load_3(s
+ 26) >> 2);
47 int64_t s11
= 2097151 & (load_4(s
+ 28) >> 7);
48 int64_t s12
= 2097151 & (load_4(s
+ 31) >> 4);
49 int64_t s13
= 2097151 & (load_3(s
+ 34) >> 1);
50 int64_t s14
= 2097151 & (load_4(s
+ 36) >> 6);
51 int64_t s15
= 2097151 & (load_3(s
+ 39) >> 3);
52 int64_t s16
= 2097151 & load_3(s
+ 42);
53 int64_t s17
= 2097151 & (load_4(s
+ 44) >> 5);
54 int64_t s18
= 2097151 & (load_3(s
+ 47) >> 2);
55 int64_t s19
= 2097151 & (load_4(s
+ 49) >> 7);
56 int64_t s20
= 2097151 & (load_4(s
+ 52) >> 4);
57 int64_t s21
= 2097151 & (load_3(s
+ 55) >> 1);
58 int64_t s22
= 2097151 & (load_4(s
+ 57) >> 6);
59 int64_t s23
= (load_4(s
+ 60) >> 3);
120 carry6
= (s6
+ (1 << 20)) >> 21;
123 carry8
= (s8
+ (1 << 20)) >> 21;
126 carry10
= (s10
+ (1 << 20)) >> 21;
128 s10
-= carry10
<< 21;
129 carry12
= (s12
+ (1 << 20)) >> 21;
131 s12
-= carry12
<< 21;
132 carry14
= (s14
+ (1 << 20)) >> 21;
134 s14
-= carry14
<< 21;
135 carry16
= (s16
+ (1 << 20)) >> 21;
137 s16
-= carry16
<< 21;
138 carry7
= (s7
+ (1 << 20)) >> 21;
141 carry9
= (s9
+ (1 << 20)) >> 21;
144 carry11
= (s11
+ (1 << 20)) >> 21;
146 s11
-= carry11
<< 21;
147 carry13
= (s13
+ (1 << 20)) >> 21;
149 s13
-= carry13
<< 21;
150 carry15
= (s15
+ (1 << 20)) >> 21;
152 s15
-= carry15
<< 21;
195 carry0
= (s0
+ (1 << 20)) >> 21;
198 carry2
= (s2
+ (1 << 20)) >> 21;
201 carry4
= (s4
+ (1 << 20)) >> 21;
204 carry6
= (s6
+ (1 << 20)) >> 21;
207 carry8
= (s8
+ (1 << 20)) >> 21;
210 carry10
= (s10
+ (1 << 20)) >> 21;
212 s10
-= carry10
<< 21;
213 carry1
= (s1
+ (1 << 20)) >> 21;
216 carry3
= (s3
+ (1 << 20)) >> 21;
219 carry5
= (s5
+ (1 << 20)) >> 21;
222 carry7
= (s7
+ (1 << 20)) >> 21;
225 carry9
= (s9
+ (1 << 20)) >> 21;
228 carry11
= (s11
+ (1 << 20)) >> 21;
230 s11
-= carry11
<< 21;
270 s10
-= carry10
<< 21;
273 s11
-= carry11
<< 21;
313 s10
-= carry10
<< 21;
315 s
[0] = (unsigned char) (s0
>> 0);
316 s
[1] = (unsigned char) (s0
>> 8);
317 s
[2] = (unsigned char) ((s0
>> 16) | (s1
<< 5));
318 s
[3] = (unsigned char) (s1
>> 3);
319 s
[4] = (unsigned char) (s1
>> 11);
320 s
[5] = (unsigned char) ((s1
>> 19) | (s2
<< 2));
321 s
[6] = (unsigned char) (s2
>> 6);
322 s
[7] = (unsigned char) ((s2
>> 14) | (s3
<< 7));
323 s
[8] = (unsigned char) (s3
>> 1);
324 s
[9] = (unsigned char) (s3
>> 9);
325 s
[10] = (unsigned char) ((s3
>> 17) | (s4
<< 4));
326 s
[11] = (unsigned char) (s4
>> 4);
327 s
[12] = (unsigned char) (s4
>> 12);
328 s
[13] = (unsigned char) ((s4
>> 20) | (s5
<< 1));
329 s
[14] = (unsigned char) (s5
>> 7);
330 s
[15] = (unsigned char) ((s5
>> 15) | (s6
<< 6));
331 s
[16] = (unsigned char) (s6
>> 2);
332 s
[17] = (unsigned char) (s6
>> 10);
333 s
[18] = (unsigned char) ((s6
>> 18) | (s7
<< 3));
334 s
[19] = (unsigned char) (s7
>> 5);
335 s
[20] = (unsigned char) (s7
>> 13);
336 s
[21] = (unsigned char) (s8
>> 0);
337 s
[22] = (unsigned char) (s8
>> 8);
338 s
[23] = (unsigned char) ((s8
>> 16) | (s9
<< 5));
339 s
[24] = (unsigned char) (s9
>> 3);
340 s
[25] = (unsigned char) (s9
>> 11);
341 s
[26] = (unsigned char) ((s9
>> 19) | (s10
<< 2));
342 s
[27] = (unsigned char) (s10
>> 6);
343 s
[28] = (unsigned char) ((s10
>> 14) | (s11
<< 7));
344 s
[29] = (unsigned char) (s11
>> 1);
345 s
[30] = (unsigned char) (s11
>> 9);
346 s
[31] = (unsigned char) (s11
>> 17);
353 a[0]+256*a[1]+...+256^31*a[31] = a
354 b[0]+256*b[1]+...+256^31*b[31] = b
355 c[0]+256*c[1]+...+256^31*c[31] = c
358 s[0]+256*s[1]+...+256^31*s[31] = (ab+c) mod l
359 where l = 2^252 + 27742317777372353535851937790883648493.
362 void sc_muladd(unsigned char *s
, const unsigned char *a
, const unsigned char *b
, const unsigned char *c
) {
363 int64_t a0
= 2097151 & load_3(a
);
364 int64_t a1
= 2097151 & (load_4(a
+ 2) >> 5);
365 int64_t a2
= 2097151 & (load_3(a
+ 5) >> 2);
366 int64_t a3
= 2097151 & (load_4(a
+ 7) >> 7);
367 int64_t a4
= 2097151 & (load_4(a
+ 10) >> 4);
368 int64_t a5
= 2097151 & (load_3(a
+ 13) >> 1);
369 int64_t a6
= 2097151 & (load_4(a
+ 15) >> 6);
370 int64_t a7
= 2097151 & (load_3(a
+ 18) >> 3);
371 int64_t a8
= 2097151 & load_3(a
+ 21);
372 int64_t a9
= 2097151 & (load_4(a
+ 23) >> 5);
373 int64_t a10
= 2097151 & (load_3(a
+ 26) >> 2);
374 int64_t a11
= (load_4(a
+ 28) >> 7);
375 int64_t b0
= 2097151 & load_3(b
);
376 int64_t b1
= 2097151 & (load_4(b
+ 2) >> 5);
377 int64_t b2
= 2097151 & (load_3(b
+ 5) >> 2);
378 int64_t b3
= 2097151 & (load_4(b
+ 7) >> 7);
379 int64_t b4
= 2097151 & (load_4(b
+ 10) >> 4);
380 int64_t b5
= 2097151 & (load_3(b
+ 13) >> 1);
381 int64_t b6
= 2097151 & (load_4(b
+ 15) >> 6);
382 int64_t b7
= 2097151 & (load_3(b
+ 18) >> 3);
383 int64_t b8
= 2097151 & load_3(b
+ 21);
384 int64_t b9
= 2097151 & (load_4(b
+ 23) >> 5);
385 int64_t b10
= 2097151 & (load_3(b
+ 26) >> 2);
386 int64_t b11
= (load_4(b
+ 28) >> 7);
387 int64_t c0
= 2097151 & load_3(c
);
388 int64_t c1
= 2097151 & (load_4(c
+ 2) >> 5);
389 int64_t c2
= 2097151 & (load_3(c
+ 5) >> 2);
390 int64_t c3
= 2097151 & (load_4(c
+ 7) >> 7);
391 int64_t c4
= 2097151 & (load_4(c
+ 10) >> 4);
392 int64_t c5
= 2097151 & (load_3(c
+ 13) >> 1);
393 int64_t c6
= 2097151 & (load_4(c
+ 15) >> 6);
394 int64_t c7
= 2097151 & (load_3(c
+ 18) >> 3);
395 int64_t c8
= 2097151 & load_3(c
+ 21);
396 int64_t c9
= 2097151 & (load_4(c
+ 23) >> 5);
397 int64_t c10
= 2097151 & (load_3(c
+ 26) >> 2);
398 int64_t c11
= (load_4(c
+ 28) >> 7);
448 s1
= c1
+ a0
* b1
+ a1
* b0
;
449 s2
= c2
+ a0
* b2
+ a1
* b1
+ a2
* b0
;
450 s3
= c3
+ a0
* b3
+ a1
* b2
+ a2
* b1
+ a3
* b0
;
451 s4
= c4
+ a0
* b4
+ a1
* b3
+ a2
* b2
+ a3
* b1
+ a4
* b0
;
452 s5
= c5
+ a0
* b5
+ a1
* b4
+ a2
* b3
+ a3
* b2
+ a4
* b1
+ a5
* b0
;
453 s6
= c6
+ a0
* b6
+ a1
* b5
+ a2
* b4
+ a3
* b3
+ a4
* b2
+ a5
* b1
+ a6
* b0
;
454 s7
= c7
+ a0
* b7
+ a1
* b6
+ a2
* b5
+ a3
* b4
+ a4
* b3
+ a5
* b2
+ a6
* b1
+ a7
* b0
;
455 s8
= c8
+ a0
* b8
+ a1
* b7
+ a2
* b6
+ a3
* b5
+ a4
* b4
+ a5
* b3
+ a6
* b2
+ a7
* b1
+ a8
* b0
;
456 s9
= c9
+ a0
* b9
+ a1
* b8
+ a2
* b7
+ a3
* b6
+ a4
* b5
+ a5
* b4
+ a6
* b3
+ a7
* b2
+ a8
* b1
+ a9
* b0
;
457 s10
= c10
+ a0
* b10
+ a1
* b9
+ a2
* b8
+ a3
* b7
+ a4
* b6
+ a5
* b5
+ a6
* b4
+ a7
* b3
+ a8
* b2
+ a9
* b1
+ a10
* b0
;
458 s11
= c11
+ a0
* b11
+ a1
* b10
+ a2
* b9
+ a3
* b8
+ a4
* b7
+ a5
* b6
+ a6
* b5
+ a7
* b4
+ a8
* b3
+ a9
* b2
+ a10
* b1
+ a11
* b0
;
459 s12
= a1
* b11
+ a2
* b10
+ a3
* b9
+ a4
* b8
+ a5
* b7
+ a6
* b6
+ a7
* b5
+ a8
* b4
+ a9
* b3
+ a10
* b2
+ a11
* b1
;
460 s13
= a2
* b11
+ a3
* b10
+ a4
* b9
+ a5
* b8
+ a6
* b7
+ a7
* b6
+ a8
* b5
+ a9
* b4
+ a10
* b3
+ a11
* b2
;
461 s14
= a3
* b11
+ a4
* b10
+ a5
* b9
+ a6
* b8
+ a7
* b7
+ a8
* b6
+ a9
* b5
+ a10
* b4
+ a11
* b3
;
462 s15
= a4
* b11
+ a5
* b10
+ a6
* b9
+ a7
* b8
+ a8
* b7
+ a9
* b6
+ a10
* b5
+ a11
* b4
;
463 s16
= a5
* b11
+ a6
* b10
+ a7
* b9
+ a8
* b8
+ a9
* b7
+ a10
* b6
+ a11
* b5
;
464 s17
= a6
* b11
+ a7
* b10
+ a8
* b9
+ a9
* b8
+ a10
* b7
+ a11
* b6
;
465 s18
= a7
* b11
+ a8
* b10
+ a9
* b9
+ a10
* b8
+ a11
* b7
;
466 s19
= a8
* b11
+ a9
* b10
+ a10
* b9
+ a11
* b8
;
467 s20
= a9
* b11
+ a10
* b10
+ a11
* b9
;
468 s21
= a10
* b11
+ a11
* b10
;
471 carry0
= (s0
+ (1 << 20)) >> 21;
474 carry2
= (s2
+ (1 << 20)) >> 21;
477 carry4
= (s4
+ (1 << 20)) >> 21;
480 carry6
= (s6
+ (1 << 20)) >> 21;
483 carry8
= (s8
+ (1 << 20)) >> 21;
486 carry10
= (s10
+ (1 << 20)) >> 21;
488 s10
-= carry10
<< 21;
489 carry12
= (s12
+ (1 << 20)) >> 21;
491 s12
-= carry12
<< 21;
492 carry14
= (s14
+ (1 << 20)) >> 21;
494 s14
-= carry14
<< 21;
495 carry16
= (s16
+ (1 << 20)) >> 21;
497 s16
-= carry16
<< 21;
498 carry18
= (s18
+ (1 << 20)) >> 21;
500 s18
-= carry18
<< 21;
501 carry20
= (s20
+ (1 << 20)) >> 21;
503 s20
-= carry20
<< 21;
504 carry22
= (s22
+ (1 << 20)) >> 21;
506 s22
-= carry22
<< 21;
507 carry1
= (s1
+ (1 << 20)) >> 21;
510 carry3
= (s3
+ (1 << 20)) >> 21;
513 carry5
= (s5
+ (1 << 20)) >> 21;
516 carry7
= (s7
+ (1 << 20)) >> 21;
519 carry9
= (s9
+ (1 << 20)) >> 21;
522 carry11
= (s11
+ (1 << 20)) >> 21;
524 s11
-= carry11
<< 21;
525 carry13
= (s13
+ (1 << 20)) >> 21;
527 s13
-= carry13
<< 21;
528 carry15
= (s15
+ (1 << 20)) >> 21;
530 s15
-= carry15
<< 21;
531 carry17
= (s17
+ (1 << 20)) >> 21;
533 s17
-= carry17
<< 21;
534 carry19
= (s19
+ (1 << 20)) >> 21;
536 s19
-= carry19
<< 21;
537 carry21
= (s21
+ (1 << 20)) >> 21;
539 s21
-= carry21
<< 21;
582 carry6
= (s6
+ (1 << 20)) >> 21;
585 carry8
= (s8
+ (1 << 20)) >> 21;
588 carry10
= (s10
+ (1 << 20)) >> 21;
590 s10
-= carry10
<< 21;
591 carry12
= (s12
+ (1 << 20)) >> 21;
593 s12
-= carry12
<< 21;
594 carry14
= (s14
+ (1 << 20)) >> 21;
596 s14
-= carry14
<< 21;
597 carry16
= (s16
+ (1 << 20)) >> 21;
599 s16
-= carry16
<< 21;
600 carry7
= (s7
+ (1 << 20)) >> 21;
603 carry9
= (s9
+ (1 << 20)) >> 21;
606 carry11
= (s11
+ (1 << 20)) >> 21;
608 s11
-= carry11
<< 21;
609 carry13
= (s13
+ (1 << 20)) >> 21;
611 s13
-= carry13
<< 21;
612 carry15
= (s15
+ (1 << 20)) >> 21;
614 s15
-= carry15
<< 21;
657 carry0
= (s0
+ (1 << 20)) >> 21;
660 carry2
= (s2
+ (1 << 20)) >> 21;
663 carry4
= (s4
+ (1 << 20)) >> 21;
666 carry6
= (s6
+ (1 << 20)) >> 21;
669 carry8
= (s8
+ (1 << 20)) >> 21;
672 carry10
= (s10
+ (1 << 20)) >> 21;
674 s10
-= carry10
<< 21;
675 carry1
= (s1
+ (1 << 20)) >> 21;
678 carry3
= (s3
+ (1 << 20)) >> 21;
681 carry5
= (s5
+ (1 << 20)) >> 21;
684 carry7
= (s7
+ (1 << 20)) >> 21;
687 carry9
= (s9
+ (1 << 20)) >> 21;
690 carry11
= (s11
+ (1 << 20)) >> 21;
692 s11
-= carry11
<< 21;
732 s10
-= carry10
<< 21;
735 s11
-= carry11
<< 21;
775 s10
-= carry10
<< 21;
777 s
[0] = (unsigned char) (s0
>> 0);
778 s
[1] = (unsigned char) (s0
>> 8);
779 s
[2] = (unsigned char) ((s0
>> 16) | (s1
<< 5));
780 s
[3] = (unsigned char) (s1
>> 3);
781 s
[4] = (unsigned char) (s1
>> 11);
782 s
[5] = (unsigned char) ((s1
>> 19) | (s2
<< 2));
783 s
[6] = (unsigned char) (s2
>> 6);
784 s
[7] = (unsigned char) ((s2
>> 14) | (s3
<< 7));
785 s
[8] = (unsigned char) (s3
>> 1);
786 s
[9] = (unsigned char) (s3
>> 9);
787 s
[10] = (unsigned char) ((s3
>> 17) | (s4
<< 4));
788 s
[11] = (unsigned char) (s4
>> 4);
789 s
[12] = (unsigned char) (s4
>> 12);
790 s
[13] = (unsigned char) ((s4
>> 20) | (s5
<< 1));
791 s
[14] = (unsigned char) (s5
>> 7);
792 s
[15] = (unsigned char) ((s5
>> 15) | (s6
<< 6));
793 s
[16] = (unsigned char) (s6
>> 2);
794 s
[17] = (unsigned char) (s6
>> 10);
795 s
[18] = (unsigned char) ((s6
>> 18) | (s7
<< 3));
796 s
[19] = (unsigned char) (s7
>> 5);
797 s
[20] = (unsigned char) (s7
>> 13);
798 s
[21] = (unsigned char) (s8
>> 0);
799 s
[22] = (unsigned char) (s8
>> 8);
800 s
[23] = (unsigned char) ((s8
>> 16) | (s9
<< 5));
801 s
[24] = (unsigned char) (s9
>> 3);
802 s
[25] = (unsigned char) (s9
>> 11);
803 s
[26] = (unsigned char) ((s9
>> 19) | (s10
<< 2));
804 s
[27] = (unsigned char) (s10
>> 6);
805 s
[28] = (unsigned char) ((s10
>> 14) | (s11
<< 7));
806 s
[29] = (unsigned char) (s11
>> 1);
807 s
[30] = (unsigned char) (s11
>> 9);
808 s
[31] = (unsigned char) (s11
>> 17);