Botan 3.6.1
Crypto and TLS for C&
sc_reduce.cpp
Go to the documentation of this file.
1/*
2* Ed25519
3* (C) 2017 Ribose Inc
4*
5* Based on the public domain code from SUPERCOP ref10 by
6* Peter Schwabe, Daniel J. Bernstein, Niels Duif, Tanja Lange, Bo-Yin Yang
7*
8* Botan is released under the Simplified BSD License (see license.txt)
9*/
10
11#include <botan/internal/ed25519_internal.h>
12
13namespace Botan {
14
15/*
16Input:
17 s[0]+256*s[1]+...+256^63*s[63] = s
18
19Output:
20 s[0]+256*s[1]+...+256^31*s[31] = s mod l
21 where l = 2^252 + 27742317777372353535851937790883648493.
22 Overwrites s in place.
23*/
24
25void sc_reduce(uint8_t* s) {
26 const uint32_t MASK = 0x1fffff;
27
28 int64_t s0 = MASK & load_3(s);
29 int64_t s1 = MASK & (load_4(s + 2) >> 5);
30 int64_t s2 = MASK & (load_3(s + 5) >> 2);
31 int64_t s3 = MASK & (load_4(s + 7) >> 7);
32 int64_t s4 = MASK & (load_4(s + 10) >> 4);
33 int64_t s5 = MASK & (load_3(s + 13) >> 1);
34 int64_t s6 = MASK & (load_4(s + 15) >> 6);
35 int64_t s7 = MASK & (load_3(s + 18) >> 3);
36 int64_t s8 = MASK & load_3(s + 21);
37 int64_t s9 = MASK & (load_4(s + 23) >> 5);
38 int64_t s10 = MASK & (load_3(s + 26) >> 2);
39 int64_t s11 = MASK & (load_4(s + 28) >> 7);
40 int64_t s12 = MASK & (load_4(s + 31) >> 4);
41 int64_t s13 = MASK & (load_3(s + 34) >> 1);
42 int64_t s14 = MASK & (load_4(s + 36) >> 6);
43 int64_t s15 = MASK & (load_3(s + 39) >> 3);
44 int64_t s16 = MASK & load_3(s + 42);
45 int64_t s17 = MASK & (load_4(s + 44) >> 5);
46 int64_t s18 = MASK & (load_3(s + 47) >> 2);
47 int64_t s19 = MASK & (load_4(s + 49) >> 7);
48 int64_t s20 = MASK & (load_4(s + 52) >> 4);
49 int64_t s21 = MASK & (load_3(s + 55) >> 1);
50 int64_t s22 = MASK & (load_4(s + 57) >> 6);
51 int64_t s23 = (load_4(s + 60) >> 3);
52
53 redc_mul(s11, s12, s13, s14, s15, s16, s23);
54 redc_mul(s10, s11, s12, s13, s14, s15, s22);
55 redc_mul(s9, s10, s11, s12, s13, s14, s21);
56 redc_mul(s8, s9, s10, s11, s12, s13, s20);
57 redc_mul(s7, s8, s9, s10, s11, s12, s19);
58 redc_mul(s6, s7, s8, s9, s10, s11, s18);
59
60 carry<21>(s6, s7);
61 carry<21>(s8, s9);
62 carry<21>(s10, s11);
63 carry<21>(s12, s13);
64 carry<21>(s14, s15);
65 carry<21>(s16, s17);
66
67 carry<21>(s7, s8);
68 carry<21>(s9, s10);
69 carry<21>(s11, s12);
70 carry<21>(s13, s14);
71 carry<21>(s15, s16);
72
73 redc_mul(s5, s6, s7, s8, s9, s10, s17);
74 redc_mul(s4, s5, s6, s7, s8, s9, s16);
75 redc_mul(s3, s4, s5, s6, s7, s8, s15);
76 redc_mul(s2, s3, s4, s5, s6, s7, s14);
77 redc_mul(s1, s2, s3, s4, s5, s6, s13);
78 redc_mul(s0, s1, s2, s3, s4, s5, s12);
79
80 carry<21>(s0, s1);
81 carry<21>(s2, s3);
82 carry<21>(s4, s5);
83 carry<21>(s6, s7);
84 carry<21>(s8, s9);
85 carry<21>(s10, s11);
86
87 carry<21>(s1, s2);
88 carry<21>(s3, s4);
89 carry<21>(s5, s6);
90 carry<21>(s7, s8);
91 carry<21>(s9, s10);
92 carry<21>(s11, s12);
93
94 redc_mul(s0, s1, s2, s3, s4, s5, s12);
95
96 carry0<21>(s0, s1);
97 carry0<21>(s1, s2);
98 carry0<21>(s2, s3);
99 carry0<21>(s3, s4);
100 carry0<21>(s4, s5);
101 carry0<21>(s5, s6);
102 carry0<21>(s6, s7);
103 carry0<21>(s7, s8);
104 carry0<21>(s8, s9);
105 carry0<21>(s9, s10);
106 carry0<21>(s10, s11);
107 carry0<21>(s11, s12);
108
109 redc_mul(s0, s1, s2, s3, s4, s5, s12);
110
111 carry0<21>(s0, s1);
112 carry0<21>(s1, s2);
113 carry0<21>(s2, s3);
114 carry0<21>(s3, s4);
115 carry0<21>(s4, s5);
116 carry0<21>(s5, s6);
117 carry0<21>(s6, s7);
118 carry0<21>(s7, s8);
119 carry0<21>(s8, s9);
120 carry0<21>(s9, s10);
121 carry0<21>(s10, s11);
122 carry0<21>(s11, s12);
123
124 s[0] = static_cast<uint8_t>(s0 >> 0);
125 s[1] = static_cast<uint8_t>(s0 >> 8);
126 s[2] = static_cast<uint8_t>((s0 >> 16) | (s1 << 5));
127 s[3] = static_cast<uint8_t>(s1 >> 3);
128 s[4] = static_cast<uint8_t>(s1 >> 11);
129 s[5] = static_cast<uint8_t>((s1 >> 19) | (s2 << 2));
130 s[6] = static_cast<uint8_t>(s2 >> 6);
131 s[7] = static_cast<uint8_t>((s2 >> 14) | (s3 << 7));
132 s[8] = static_cast<uint8_t>(s3 >> 1);
133 s[9] = static_cast<uint8_t>(s3 >> 9);
134 s[10] = static_cast<uint8_t>((s3 >> 17) | (s4 << 4));
135 s[11] = static_cast<uint8_t>(s4 >> 4);
136 s[12] = static_cast<uint8_t>(s4 >> 12);
137 s[13] = static_cast<uint8_t>((s4 >> 20) | (s5 << 1));
138 s[14] = static_cast<uint8_t>(s5 >> 7);
139 s[15] = static_cast<uint8_t>((s5 >> 15) | (s6 << 6));
140 s[16] = static_cast<uint8_t>(s6 >> 2);
141 s[17] = static_cast<uint8_t>(s6 >> 10);
142 s[18] = static_cast<uint8_t>((s6 >> 18) | (s7 << 3));
143 s[19] = static_cast<uint8_t>(s7 >> 5);
144 s[20] = static_cast<uint8_t>(s7 >> 13);
145 s[21] = static_cast<uint8_t>(s8 >> 0);
146 s[22] = static_cast<uint8_t>(s8 >> 8);
147 s[23] = static_cast<uint8_t>((s8 >> 16) | (s9 << 5));
148 s[24] = static_cast<uint8_t>(s9 >> 3);
149 s[25] = static_cast<uint8_t>(s9 >> 11);
150 s[26] = static_cast<uint8_t>((s9 >> 19) | (s10 << 2));
151 s[27] = static_cast<uint8_t>(s10 >> 6);
152 s[28] = static_cast<uint8_t>((s10 >> 14) | (s11 << 7));
153 s[29] = static_cast<uint8_t>(s11 >> 1);
154 s[30] = static_cast<uint8_t>(s11 >> 9);
155 s[31] = static_cast<uint8_t>(s11 >> 17);
156}
157
158} // namespace Botan
void redc_mul(int64_t &s1, int64_t &s2, int64_t &s3, int64_t &s4, int64_t &s5, int64_t &s6, int64_t &X)
uint64_t load_4(const uint8_t *in)
void carry0(int64_t &h0, int64_t &h1)
void carry(int64_t &h0, int64_t &h1)
void sc_reduce(uint8_t *)
Definition sc_reduce.cpp:25
uint64_t load_3(const uint8_t in[3])