ed25519 1.0.0-jruby → 1.1.0-jruby
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/.gitignore +1 -0
- data/CHANGES.md +13 -0
- data/README.md +9 -9
- data/Rakefile +3 -3
- data/ext/ed25519_jruby/LICENSE.txt +123 -0
- data/ext/ed25519_jruby/README.md +77 -0
- data/ext/ed25519_jruby/net/i2p/crypto/eddsa/EdDSAEngine.java +491 -0
- data/ext/ed25519_jruby/net/i2p/crypto/eddsa/EdDSAKey.java +31 -0
- data/ext/ed25519_jruby/net/i2p/crypto/eddsa/EdDSAPrivateKey.java +338 -0
- data/ext/ed25519_jruby/net/i2p/crypto/eddsa/EdDSAPublicKey.java +275 -0
- data/ext/ed25519_jruby/net/i2p/crypto/eddsa/EdDSASecurityProvider.java +59 -0
- data/ext/ed25519_jruby/net/i2p/crypto/eddsa/KeyFactory.java +75 -0
- data/ext/ed25519_jruby/net/i2p/crypto/eddsa/KeyPairGenerator.java +97 -0
- data/ext/ed25519_jruby/net/i2p/crypto/eddsa/Utils.java +103 -0
- data/ext/ed25519_jruby/net/i2p/crypto/eddsa/math/Constants.java +23 -0
- data/ext/ed25519_jruby/net/i2p/crypto/eddsa/math/Curve.java +100 -0
- data/ext/ed25519_jruby/net/i2p/crypto/eddsa/math/Encoding.java +54 -0
- data/ext/ed25519_jruby/net/i2p/crypto/eddsa/math/Field.java +99 -0
- data/ext/ed25519_jruby/net/i2p/crypto/eddsa/math/FieldElement.java +76 -0
- data/ext/ed25519_jruby/net/i2p/crypto/eddsa/math/GroupElement.java +1034 -0
- data/ext/ed25519_jruby/net/i2p/crypto/eddsa/math/ScalarOps.java +34 -0
- data/ext/ed25519_jruby/net/i2p/crypto/eddsa/math/bigint/BigIntegerFieldElement.java +131 -0
- data/ext/ed25519_jruby/net/i2p/crypto/eddsa/math/bigint/BigIntegerLittleEndianEncoding.java +102 -0
- data/ext/ed25519_jruby/net/i2p/crypto/eddsa/math/bigint/BigIntegerScalarOps.java +37 -0
- data/ext/ed25519_jruby/net/i2p/crypto/eddsa/math/bigint/package.html +6 -0
- data/ext/ed25519_jruby/net/i2p/crypto/eddsa/math/ed25519/Ed25519FieldElement.java +988 -0
- data/ext/ed25519_jruby/net/i2p/crypto/eddsa/math/ed25519/Ed25519LittleEndianEncoding.java +256 -0
- data/ext/ed25519_jruby/net/i2p/crypto/eddsa/math/ed25519/Ed25519ScalarOps.java +693 -0
- data/ext/ed25519_jruby/net/i2p/crypto/eddsa/spec/EdDSAGenParameterSpec.java +32 -0
- data/ext/ed25519_jruby/net/i2p/crypto/eddsa/spec/EdDSANamedCurveSpec.java +35 -0
- data/ext/ed25519_jruby/net/i2p/crypto/eddsa/spec/EdDSANamedCurveTable.java +71 -0
- data/ext/ed25519_jruby/net/i2p/crypto/eddsa/spec/EdDSAParameterSpec.java +97 -0
- data/ext/ed25519_jruby/net/i2p/crypto/eddsa/spec/EdDSAPrivateKeySpec.java +133 -0
- data/ext/ed25519_jruby/net/i2p/crypto/eddsa/spec/EdDSAPublicKeySpec.java +61 -0
- data/ext/ed25519_jruby/org/cryptosphere/Ed25519Provider.java +95 -0
- data/lib/ed25519.rb +8 -8
- data/lib/ed25519/signing_key.rb +9 -0
- data/lib/ed25519/version.rb +1 -1
- data/lib/ed25519_java.jar +0 -0
- metadata +32 -3
- data/ext/ed25519_java/org/cryptosphere/ed25519.java +0 -228
- data/lib/ed25519/provider/jruby.rb +0 -39
@@ -0,0 +1,256 @@
|
|
1
|
+
/**
|
2
|
+
* EdDSA-Java by str4d
|
3
|
+
*
|
4
|
+
* To the extent possible under law, the person who associated CC0 with
|
5
|
+
* EdDSA-Java has waived all copyright and related or neighboring rights
|
6
|
+
* to EdDSA-Java.
|
7
|
+
*
|
8
|
+
* You should have received a copy of the CC0 legalcode along with this
|
9
|
+
* work. If not, see <https://creativecommons.org/publicdomain/zero/1.0/>.
|
10
|
+
*
|
11
|
+
*/
|
12
|
+
package net.i2p.crypto.eddsa.math.ed25519;
|
13
|
+
|
14
|
+
import net.i2p.crypto.eddsa.math.*;
|
15
|
+
|
16
|
+
/**
|
17
|
+
* Helper class for encoding/decoding from/to the 32 byte representation.
|
18
|
+
* <p>
|
19
|
+
* Reviewed/commented by Bloody Rookie (nemproject@gmx.de)
|
20
|
+
*/
|
21
|
+
public class Ed25519LittleEndianEncoding extends Encoding {
|
22
|
+
/**
|
23
|
+
* Encodes a given field element in its 32 byte representation. This is done in two steps:
|
24
|
+
* <ol>
|
25
|
+
* <li>Reduce the value of the field element modulo $p$.
|
26
|
+
* <li>Convert the field element to the 32 byte representation.
|
27
|
+
* </ol><p>
|
28
|
+
* The idea for the modulo $p$ reduction algorithm is as follows:
|
29
|
+
* </p>
|
30
|
+
* <h2>Assumption:</h2>
|
31
|
+
* <ul>
|
32
|
+
* <li>$p = 2^{255} - 19$
|
33
|
+
* <li>$h = h_0 + 2^{25} * h_1 + 2^{(26+25)} * h_2 + \dots + 2^{230} * h_9$ where $0 \le |h_i| \lt 2^{27}$ for all $i=0,\dots,9$.
|
34
|
+
* <li>$h \cong r \mod p$, i.e. $h = r + q * p$ for some suitable $0 \le r \lt p$ and an integer $q$.
|
35
|
+
* </ul><p>
|
36
|
+
* Then $q = [2^{-255} * (h + 19 * 2^{-25} * h_9 + 1/2)]$ where $[x] = floor(x)$.
|
37
|
+
* </p>
|
38
|
+
* <h2>Proof:</h2>
|
39
|
+
* <p>
|
40
|
+
* We begin with some very raw estimation for the bounds of some expressions:
|
41
|
+
* <p>
|
42
|
+
* $$
|
43
|
+
* \begin{equation}
|
44
|
+
* |h| \lt 2^{230} * 2^{30} = 2^{260} \Rightarrow |r + q * p| \lt 2^{260} \Rightarrow |q| \lt 2^{10}. \\
|
45
|
+
* \Rightarrow -1/4 \le a := 19^2 * 2^{-255} * q \lt 1/4. \\
|
46
|
+
* |h - 2^{230} * h_9| = |h_0 + \dots + 2^{204} * h_8| \lt 2^{204} * 2^{30} = 2^{234}. \\
|
47
|
+
* \Rightarrow -1/4 \le b := 19 * 2^{-255} * (h - 2^{230} * h_9) \lt 1/4
|
48
|
+
* \end{equation}
|
49
|
+
* $$
|
50
|
+
* <p>
|
51
|
+
* Therefore $0 \lt 1/2 - a - b \lt 1$.
|
52
|
+
* <p>
|
53
|
+
* Set $x := r + 19 * 2^{-255} * r + 1/2 - a - b$. Then:
|
54
|
+
* <p>
|
55
|
+
* $$
|
56
|
+
* 0 \le x \lt 255 - 20 + 19 + 1 = 2^{255} \\
|
57
|
+
* \Rightarrow 0 \le 2^{-255} * x \lt 1.
|
58
|
+
* $$
|
59
|
+
* <p>
|
60
|
+
* Since $q$ is an integer we have
|
61
|
+
* <p>
|
62
|
+
* $$
|
63
|
+
* [q + 2^{-255} * x] = q \quad (1)
|
64
|
+
* $$
|
65
|
+
* <p>
|
66
|
+
* Have a closer look at $x$:
|
67
|
+
* <p>
|
68
|
+
* $$
|
69
|
+
* \begin{align}
|
70
|
+
* x &= h - q * (2^{255} - 19) + 19 * 2^{-255} * (h - q * (2^{255} - 19)) + 1/2 - 19^2 * 2^{-255} * q - 19 * 2^{-255} * (h - 2^{230} * h_9) \\
|
71
|
+
* &= h - q * 2^{255} + 19 * q + 19 * 2^{-255} * h - 19 * q + 19^2 * 2^{-255} * q + 1/2 - 19^2 * 2^{-255} * q - 19 * 2^{-255} * h + 19 * 2^{-25} * h_9 \\
|
72
|
+
* &= h + 19 * 2^{-25} * h_9 + 1/2 - q^{255}.
|
73
|
+
* \end{align}
|
74
|
+
* $$
|
75
|
+
* <p>
|
76
|
+
* Inserting the expression for $x$ into $(1)$ we get the desired expression for $q$.
|
77
|
+
*/
|
78
|
+
public byte[] encode(FieldElement x) {
|
79
|
+
int[] h = ((Ed25519FieldElement)x).t;
|
80
|
+
int h0 = h[0];
|
81
|
+
int h1 = h[1];
|
82
|
+
int h2 = h[2];
|
83
|
+
int h3 = h[3];
|
84
|
+
int h4 = h[4];
|
85
|
+
int h5 = h[5];
|
86
|
+
int h6 = h[6];
|
87
|
+
int h7 = h[7];
|
88
|
+
int h8 = h[8];
|
89
|
+
int h9 = h[9];
|
90
|
+
int q;
|
91
|
+
int carry0;
|
92
|
+
int carry1;
|
93
|
+
int carry2;
|
94
|
+
int carry3;
|
95
|
+
int carry4;
|
96
|
+
int carry5;
|
97
|
+
int carry6;
|
98
|
+
int carry7;
|
99
|
+
int carry8;
|
100
|
+
int carry9;
|
101
|
+
|
102
|
+
// Step 1:
|
103
|
+
// Calculate q
|
104
|
+
q = (19 * h9 + (1 << 24)) >> 25;
|
105
|
+
q = (h0 + q) >> 26;
|
106
|
+
q = (h1 + q) >> 25;
|
107
|
+
q = (h2 + q) >> 26;
|
108
|
+
q = (h3 + q) >> 25;
|
109
|
+
q = (h4 + q) >> 26;
|
110
|
+
q = (h5 + q) >> 25;
|
111
|
+
q = (h6 + q) >> 26;
|
112
|
+
q = (h7 + q) >> 25;
|
113
|
+
q = (h8 + q) >> 26;
|
114
|
+
q = (h9 + q) >> 25;
|
115
|
+
|
116
|
+
// r = h - q * p = h - 2^255 * q + 19 * q
|
117
|
+
// First add 19 * q then discard the bit 255
|
118
|
+
h0 += 19 * q;
|
119
|
+
|
120
|
+
carry0 = h0 >> 26; h1 += carry0; h0 -= carry0 << 26;
|
121
|
+
carry1 = h1 >> 25; h2 += carry1; h1 -= carry1 << 25;
|
122
|
+
carry2 = h2 >> 26; h3 += carry2; h2 -= carry2 << 26;
|
123
|
+
carry3 = h3 >> 25; h4 += carry3; h3 -= carry3 << 25;
|
124
|
+
carry4 = h4 >> 26; h5 += carry4; h4 -= carry4 << 26;
|
125
|
+
carry5 = h5 >> 25; h6 += carry5; h5 -= carry5 << 25;
|
126
|
+
carry6 = h6 >> 26; h7 += carry6; h6 -= carry6 << 26;
|
127
|
+
carry7 = h7 >> 25; h8 += carry7; h7 -= carry7 << 25;
|
128
|
+
carry8 = h8 >> 26; h9 += carry8; h8 -= carry8 << 26;
|
129
|
+
carry9 = h9 >> 25; h9 -= carry9 << 25;
|
130
|
+
|
131
|
+
// Step 2 (straight forward conversion):
|
132
|
+
byte[] s = new byte[32];
|
133
|
+
s[0] = (byte) h0;
|
134
|
+
s[1] = (byte) (h0 >> 8);
|
135
|
+
s[2] = (byte) (h0 >> 16);
|
136
|
+
s[3] = (byte) ((h0 >> 24) | (h1 << 2));
|
137
|
+
s[4] = (byte) (h1 >> 6);
|
138
|
+
s[5] = (byte) (h1 >> 14);
|
139
|
+
s[6] = (byte) ((h1 >> 22) | (h2 << 3));
|
140
|
+
s[7] = (byte) (h2 >> 5);
|
141
|
+
s[8] = (byte) (h2 >> 13);
|
142
|
+
s[9] = (byte) ((h2 >> 21) | (h3 << 5));
|
143
|
+
s[10] = (byte) (h3 >> 3);
|
144
|
+
s[11] = (byte) (h3 >> 11);
|
145
|
+
s[12] = (byte) ((h3 >> 19) | (h4 << 6));
|
146
|
+
s[13] = (byte) (h4 >> 2);
|
147
|
+
s[14] = (byte) (h4 >> 10);
|
148
|
+
s[15] = (byte) (h4 >> 18);
|
149
|
+
s[16] = (byte) h5;
|
150
|
+
s[17] = (byte) (h5 >> 8);
|
151
|
+
s[18] = (byte) (h5 >> 16);
|
152
|
+
s[19] = (byte) ((h5 >> 24) | (h6 << 1));
|
153
|
+
s[20] = (byte) (h6 >> 7);
|
154
|
+
s[21] = (byte) (h6 >> 15);
|
155
|
+
s[22] = (byte) ((h6 >> 23) | (h7 << 3));
|
156
|
+
s[23] = (byte) (h7 >> 5);
|
157
|
+
s[24] = (byte) (h7 >> 13);
|
158
|
+
s[25] = (byte) ((h7 >> 21) | (h8 << 4));
|
159
|
+
s[26] = (byte) (h8 >> 4);
|
160
|
+
s[27] = (byte) (h8 >> 12);
|
161
|
+
s[28] = (byte) ((h8 >> 20) | (h9 << 6));
|
162
|
+
s[29] = (byte) (h9 >> 2);
|
163
|
+
s[30] = (byte) (h9 >> 10);
|
164
|
+
s[31] = (byte) (h9 >> 18);
|
165
|
+
return s;
|
166
|
+
}
|
167
|
+
|
168
|
+
static int load_3(byte[] in, int offset) {
|
169
|
+
int result = in[offset++] & 0xff;
|
170
|
+
result |= (in[offset++] & 0xff) << 8;
|
171
|
+
result |= (in[offset] & 0xff) << 16;
|
172
|
+
return result;
|
173
|
+
}
|
174
|
+
|
175
|
+
static long load_4(byte[] in, int offset) {
|
176
|
+
int result = in[offset++] & 0xff;
|
177
|
+
result |= (in[offset++] & 0xff) << 8;
|
178
|
+
result |= (in[offset++] & 0xff) << 16;
|
179
|
+
result |= in[offset] << 24;
|
180
|
+
return ((long)result) & 0xffffffffL;
|
181
|
+
}
|
182
|
+
|
183
|
+
/**
|
184
|
+
* Decodes a given field element in its 10 byte $2^{25.5}$ representation.
|
185
|
+
*
|
186
|
+
* @param in The 32 byte representation.
|
187
|
+
* @return The field element in its $2^{25.5}$ bit representation.
|
188
|
+
*/
|
189
|
+
public FieldElement decode(byte[] in) {
|
190
|
+
long h0 = load_4(in, 0);
|
191
|
+
long h1 = load_3(in, 4) << 6;
|
192
|
+
long h2 = load_3(in, 7) << 5;
|
193
|
+
long h3 = load_3(in, 10) << 3;
|
194
|
+
long h4 = load_3(in, 13) << 2;
|
195
|
+
long h5 = load_4(in, 16);
|
196
|
+
long h6 = load_3(in, 20) << 7;
|
197
|
+
long h7 = load_3(in, 23) << 5;
|
198
|
+
long h8 = load_3(in, 26) << 4;
|
199
|
+
long h9 = (load_3(in, 29) & 0x7FFFFF) << 2;
|
200
|
+
long carry0;
|
201
|
+
long carry1;
|
202
|
+
long carry2;
|
203
|
+
long carry3;
|
204
|
+
long carry4;
|
205
|
+
long carry5;
|
206
|
+
long carry6;
|
207
|
+
long carry7;
|
208
|
+
long carry8;
|
209
|
+
long carry9;
|
210
|
+
|
211
|
+
// Remember: 2^255 congruent 19 modulo p
|
212
|
+
carry9 = (h9 + (long) (1<<24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25;
|
213
|
+
carry1 = (h1 + (long) (1<<24)) >> 25; h2 += carry1; h1 -= carry1 << 25;
|
214
|
+
carry3 = (h3 + (long) (1<<24)) >> 25; h4 += carry3; h3 -= carry3 << 25;
|
215
|
+
carry5 = (h5 + (long) (1<<24)) >> 25; h6 += carry5; h5 -= carry5 << 25;
|
216
|
+
carry7 = (h7 + (long) (1<<24)) >> 25; h8 += carry7; h7 -= carry7 << 25;
|
217
|
+
|
218
|
+
carry0 = (h0 + (long) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26;
|
219
|
+
carry2 = (h2 + (long) (1<<25)) >> 26; h3 += carry2; h2 -= carry2 << 26;
|
220
|
+
carry4 = (h4 + (long) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26;
|
221
|
+
carry6 = (h6 + (long) (1<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26;
|
222
|
+
carry8 = (h8 + (long) (1<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26;
|
223
|
+
|
224
|
+
int[] h = new int[10];
|
225
|
+
h[0] = (int) h0;
|
226
|
+
h[1] = (int) h1;
|
227
|
+
h[2] = (int) h2;
|
228
|
+
h[3] = (int) h3;
|
229
|
+
h[4] = (int) h4;
|
230
|
+
h[5] = (int) h5;
|
231
|
+
h[6] = (int) h6;
|
232
|
+
h[7] = (int) h7;
|
233
|
+
h[8] = (int) h8;
|
234
|
+
h[9] = (int) h9;
|
235
|
+
return new Ed25519FieldElement(f, h);
|
236
|
+
}
|
237
|
+
|
238
|
+
/**
|
239
|
+
* Is the FieldElement negative in this encoding?
|
240
|
+
* <p>
|
241
|
+
* Return true if $x$ is in $\{1,3,5,\dots,q-2\}$<br>
|
242
|
+
* Return false if $x$ is in $\{0,2,4,\dots,q-1\}$
|
243
|
+
* <p>
|
244
|
+
* Preconditions:
|
245
|
+
* </p><ul>
|
246
|
+
* <li>$|x|$ bounded by $1.1*2^{26},1.1*2^{25},1.1*2^{26},1.1*2^{25}$, etc.
|
247
|
+
* </ul>
|
248
|
+
*
|
249
|
+
* @return true if $x$ is in $\{1,3,5,\dots,q-2\}$, false otherwise.
|
250
|
+
*/
|
251
|
+
public boolean isNegative(FieldElement x) {
|
252
|
+
byte[] s = encode(x);
|
253
|
+
return (s[0] & 1) != 0;
|
254
|
+
}
|
255
|
+
|
256
|
+
}
|
@@ -0,0 +1,693 @@
|
|
1
|
+
/**
|
2
|
+
* EdDSA-Java by str4d
|
3
|
+
*
|
4
|
+
* To the extent possible under law, the person who associated CC0 with
|
5
|
+
* EdDSA-Java has waived all copyright and related or neighboring rights
|
6
|
+
* to EdDSA-Java.
|
7
|
+
*
|
8
|
+
* You should have received a copy of the CC0 legalcode along with this
|
9
|
+
* work. If not, see <https://creativecommons.org/publicdomain/zero/1.0/>.
|
10
|
+
*
|
11
|
+
*/
|
12
|
+
package net.i2p.crypto.eddsa.math.ed25519;
|
13
|
+
|
14
|
+
import net.i2p.crypto.eddsa.math.ScalarOps;
|
15
|
+
import static net.i2p.crypto.eddsa.math.ed25519.Ed25519LittleEndianEncoding.load_3;
|
16
|
+
import static net.i2p.crypto.eddsa.math.ed25519.Ed25519LittleEndianEncoding.load_4;
|
17
|
+
|
18
|
+
/**
|
19
|
+
* Class for reducing a huge integer modulo the group order q and
|
20
|
+
* doing a combined multiply plus add plus reduce operation.
|
21
|
+
* <p>
|
22
|
+
* $q = 2^{252} + 27742317777372353535851937790883648493$.
|
23
|
+
* <p>
|
24
|
+
* Reviewed/commented by Bloody Rookie (nemproject@gmx.de)
|
25
|
+
*/
|
26
|
+
public class Ed25519ScalarOps implements ScalarOps {
|
27
|
+
|
28
|
+
/**
|
29
|
+
* Reduction modulo the group order $q$.
|
30
|
+
* <p>
|
31
|
+
* Input:
|
32
|
+
* $s[0]+256*s[1]+\dots+256^{63}*s[63] = s$
|
33
|
+
* <p>
|
34
|
+
* Output:
|
35
|
+
* $s[0]+256*s[1]+\dots+256^{31}*s[31] = s \bmod q$
|
36
|
+
* where $q = 2^{252} + 27742317777372353535851937790883648493$.
|
37
|
+
*/
|
38
|
+
public byte[] reduce(byte[] s) {
|
39
|
+
// s0,..., s22 have 21 bits, s23 has 29 bits
|
40
|
+
long s0 = 0x1FFFFF & load_3(s, 0);
|
41
|
+
long s1 = 0x1FFFFF & (load_4(s, 2) >> 5);
|
42
|
+
long s2 = 0x1FFFFF & (load_3(s, 5) >> 2);
|
43
|
+
long s3 = 0x1FFFFF & (load_4(s, 7) >> 7);
|
44
|
+
long s4 = 0x1FFFFF & (load_4(s, 10) >> 4);
|
45
|
+
long s5 = 0x1FFFFF & (load_3(s, 13) >> 1);
|
46
|
+
long s6 = 0x1FFFFF & (load_4(s, 15) >> 6);
|
47
|
+
long s7 = 0x1FFFFF & (load_3(s, 18) >> 3);
|
48
|
+
long s8 = 0x1FFFFF & load_3(s, 21);
|
49
|
+
long s9 = 0x1FFFFF & (load_4(s, 23) >> 5);
|
50
|
+
long s10 = 0x1FFFFF & (load_3(s, 26) >> 2);
|
51
|
+
long s11 = 0x1FFFFF & (load_4(s, 28) >> 7);
|
52
|
+
long s12 = 0x1FFFFF & (load_4(s, 31) >> 4);
|
53
|
+
long s13 = 0x1FFFFF & (load_3(s, 34) >> 1);
|
54
|
+
long s14 = 0x1FFFFF & (load_4(s, 36) >> 6);
|
55
|
+
long s15 = 0x1FFFFF & (load_3(s, 39) >> 3);
|
56
|
+
long s16 = 0x1FFFFF & load_3(s, 42);
|
57
|
+
long s17 = 0x1FFFFF & (load_4(s, 44) >> 5);
|
58
|
+
long s18 = 0x1FFFFF & (load_3(s, 47) >> 2);
|
59
|
+
long s19 = 0x1FFFFF & (load_4(s, 49) >> 7);
|
60
|
+
long s20 = 0x1FFFFF & (load_4(s, 52) >> 4);
|
61
|
+
long s21 = 0x1FFFFF & (load_3(s, 55) >> 1);
|
62
|
+
long s22 = 0x1FFFFF & (load_4(s, 57) >> 6);
|
63
|
+
long s23 = (load_4(s, 60) >> 3);
|
64
|
+
long carry0;
|
65
|
+
long carry1;
|
66
|
+
long carry2;
|
67
|
+
long carry3;
|
68
|
+
long carry4;
|
69
|
+
long carry5;
|
70
|
+
long carry6;
|
71
|
+
long carry7;
|
72
|
+
long carry8;
|
73
|
+
long carry9;
|
74
|
+
long carry10;
|
75
|
+
long carry11;
|
76
|
+
long carry12;
|
77
|
+
long carry13;
|
78
|
+
long carry14;
|
79
|
+
long carry15;
|
80
|
+
long carry16;
|
81
|
+
|
82
|
+
/**
|
83
|
+
* Lots of magic numbers :)
|
84
|
+
* To understand what's going on below, note that
|
85
|
+
*
|
86
|
+
* (1) q = 2^252 + q0 where q0 = 27742317777372353535851937790883648493.
|
87
|
+
* (2) s11 is the coefficient of 2^(11*21), s23 is the coefficient of 2^(^23*21) and 2^252 = 2^((23-11) * 21)).
|
88
|
+
* (3) 2^252 congruent -q0 modulo q.
|
89
|
+
* (4) -q0 = 666643 * 2^0 + 470296 * 2^21 + 654183 * 2^(2*21) - 997805 * 2^(3*21) + 136657 * 2^(4*21) - 683901 * 2^(5*21)
|
90
|
+
*
|
91
|
+
* Thus
|
92
|
+
* s23 * 2^(23*11) = s23 * 2^(12*21) * 2^(11*21) = s3 * 2^252 * 2^(11*21) congruent
|
93
|
+
* s23 * (666643 * 2^0 + 470296 * 2^21 + 654183 * 2^(2*21) - 997805 * 2^(3*21) + 136657 * 2^(4*21) - 683901 * 2^(5*21)) * 2^(11*21) modulo q =
|
94
|
+
* s23 * (666643 * 2^(11*21) + 470296 * 2^(12*21) + 654183 * 2^(13*21) - 997805 * 2^(14*21) + 136657 * 2^(15*21) - 683901 * 2^(16*21)).
|
95
|
+
*
|
96
|
+
* The same procedure is then applied for s22,...,s18.
|
97
|
+
*/
|
98
|
+
s11 += s23 * 666643;
|
99
|
+
s12 += s23 * 470296;
|
100
|
+
s13 += s23 * 654183;
|
101
|
+
s14 -= s23 * 997805;
|
102
|
+
s15 += s23 * 136657;
|
103
|
+
s16 -= s23 * 683901;
|
104
|
+
// not used again
|
105
|
+
//s23 = 0;
|
106
|
+
|
107
|
+
s10 += s22 * 666643;
|
108
|
+
s11 += s22 * 470296;
|
109
|
+
s12 += s22 * 654183;
|
110
|
+
s13 -= s22 * 997805;
|
111
|
+
s14 += s22 * 136657;
|
112
|
+
s15 -= s22 * 683901;
|
113
|
+
// not used again
|
114
|
+
//s22 = 0;
|
115
|
+
|
116
|
+
s9 += s21 * 666643;
|
117
|
+
s10 += s21 * 470296;
|
118
|
+
s11 += s21 * 654183;
|
119
|
+
s12 -= s21 * 997805;
|
120
|
+
s13 += s21 * 136657;
|
121
|
+
s14 -= s21 * 683901;
|
122
|
+
// not used again
|
123
|
+
//s21 = 0;
|
124
|
+
|
125
|
+
s8 += s20 * 666643;
|
126
|
+
s9 += s20 * 470296;
|
127
|
+
s10 += s20 * 654183;
|
128
|
+
s11 -= s20 * 997805;
|
129
|
+
s12 += s20 * 136657;
|
130
|
+
s13 -= s20 * 683901;
|
131
|
+
// not used again
|
132
|
+
//s20 = 0;
|
133
|
+
|
134
|
+
s7 += s19 * 666643;
|
135
|
+
s8 += s19 * 470296;
|
136
|
+
s9 += s19 * 654183;
|
137
|
+
s10 -= s19 * 997805;
|
138
|
+
s11 += s19 * 136657;
|
139
|
+
s12 -= s19 * 683901;
|
140
|
+
// not used again
|
141
|
+
//s19 = 0;
|
142
|
+
|
143
|
+
s6 += s18 * 666643;
|
144
|
+
s7 += s18 * 470296;
|
145
|
+
s8 += s18 * 654183;
|
146
|
+
s9 -= s18 * 997805;
|
147
|
+
s10 += s18 * 136657;
|
148
|
+
s11 -= s18 * 683901;
|
149
|
+
// not used again
|
150
|
+
//s18 = 0;
|
151
|
+
|
152
|
+
/**
|
153
|
+
* Time to reduce the coefficient in order not to get an overflow.
|
154
|
+
*/
|
155
|
+
carry6 = (s6 + (1<<20)) >> 21; s7 += carry6; s6 -= carry6 << 21;
|
156
|
+
carry8 = (s8 + (1<<20)) >> 21; s9 += carry8; s8 -= carry8 << 21;
|
157
|
+
carry10 = (s10 + (1<<20)) >> 21; s11 += carry10; s10 -= carry10 << 21;
|
158
|
+
carry12 = (s12 + (1<<20)) >> 21; s13 += carry12; s12 -= carry12 << 21;
|
159
|
+
carry14 = (s14 + (1<<20)) >> 21; s15 += carry14; s14 -= carry14 << 21;
|
160
|
+
carry16 = (s16 + (1<<20)) >> 21; s17 += carry16; s16 -= carry16 << 21;
|
161
|
+
|
162
|
+
carry7 = (s7 + (1<<20)) >> 21; s8 += carry7; s7 -= carry7 << 21;
|
163
|
+
carry9 = (s9 + (1<<20)) >> 21; s10 += carry9; s9 -= carry9 << 21;
|
164
|
+
carry11 = (s11 + (1<<20)) >> 21; s12 += carry11; s11 -= carry11 << 21;
|
165
|
+
carry13 = (s13 + (1<<20)) >> 21; s14 += carry13; s13 -= carry13 << 21;
|
166
|
+
carry15 = (s15 + (1<<20)) >> 21; s16 += carry15; s15 -= carry15 << 21;
|
167
|
+
|
168
|
+
/**
|
169
|
+
* Continue with above procedure.
|
170
|
+
*/
|
171
|
+
s5 += s17 * 666643;
|
172
|
+
s6 += s17 * 470296;
|
173
|
+
s7 += s17 * 654183;
|
174
|
+
s8 -= s17 * 997805;
|
175
|
+
s9 += s17 * 136657;
|
176
|
+
s10 -= s17 * 683901;
|
177
|
+
// not used again
|
178
|
+
//s17 = 0;
|
179
|
+
|
180
|
+
s4 += s16 * 666643;
|
181
|
+
s5 += s16 * 470296;
|
182
|
+
s6 += s16 * 654183;
|
183
|
+
s7 -= s16 * 997805;
|
184
|
+
s8 += s16 * 136657;
|
185
|
+
s9 -= s16 * 683901;
|
186
|
+
// not used again
|
187
|
+
//s16 = 0;
|
188
|
+
|
189
|
+
s3 += s15 * 666643;
|
190
|
+
s4 += s15 * 470296;
|
191
|
+
s5 += s15 * 654183;
|
192
|
+
s6 -= s15 * 997805;
|
193
|
+
s7 += s15 * 136657;
|
194
|
+
s8 -= s15 * 683901;
|
195
|
+
// not used again
|
196
|
+
//s15 = 0;
|
197
|
+
|
198
|
+
s2 += s14 * 666643;
|
199
|
+
s3 += s14 * 470296;
|
200
|
+
s4 += s14 * 654183;
|
201
|
+
s5 -= s14 * 997805;
|
202
|
+
s6 += s14 * 136657;
|
203
|
+
s7 -= s14 * 683901;
|
204
|
+
// not used again
|
205
|
+
//s14 = 0;
|
206
|
+
|
207
|
+
s1 += s13 * 666643;
|
208
|
+
s2 += s13 * 470296;
|
209
|
+
s3 += s13 * 654183;
|
210
|
+
s4 -= s13 * 997805;
|
211
|
+
s5 += s13 * 136657;
|
212
|
+
s6 -= s13 * 683901;
|
213
|
+
// not used again
|
214
|
+
//s13 = 0;
|
215
|
+
|
216
|
+
s0 += s12 * 666643;
|
217
|
+
s1 += s12 * 470296;
|
218
|
+
s2 += s12 * 654183;
|
219
|
+
s3 -= s12 * 997805;
|
220
|
+
s4 += s12 * 136657;
|
221
|
+
s5 -= s12 * 683901;
|
222
|
+
// set below
|
223
|
+
//s12 = 0;
|
224
|
+
|
225
|
+
/**
|
226
|
+
* Reduce coefficients again.
|
227
|
+
*/
|
228
|
+
carry0 = (s0 + (1<<20)) >> 21; s1 += carry0; s0 -= carry0 << 21;
|
229
|
+
carry2 = (s2 + (1<<20)) >> 21; s3 += carry2; s2 -= carry2 << 21;
|
230
|
+
carry4 = (s4 + (1<<20)) >> 21; s5 += carry4; s4 -= carry4 << 21;
|
231
|
+
carry6 = (s6 + (1<<20)) >> 21; s7 += carry6; s6 -= carry6 << 21;
|
232
|
+
carry8 = (s8 + (1<<20)) >> 21; s9 += carry8; s8 -= carry8 << 21;
|
233
|
+
carry10 = (s10 + (1<<20)) >> 21; s11 += carry10; s10 -= carry10 << 21;
|
234
|
+
|
235
|
+
carry1 = (s1 + (1<<20)) >> 21; s2 += carry1; s1 -= carry1 << 21;
|
236
|
+
carry3 = (s3 + (1<<20)) >> 21; s4 += carry3; s3 -= carry3 << 21;
|
237
|
+
carry5 = (s5 + (1<<20)) >> 21; s6 += carry5; s5 -= carry5 << 21;
|
238
|
+
carry7 = (s7 + (1<<20)) >> 21; s8 += carry7; s7 -= carry7 << 21;
|
239
|
+
carry9 = (s9 + (1<<20)) >> 21; s10 += carry9; s9 -= carry9 << 21;
|
240
|
+
//carry11 = (s11 + (1<<20)) >> 21; s12 += carry11; s11 -= carry11 << 21;
|
241
|
+
carry11 = (s11 + (1<<20)) >> 21; s12 = carry11; s11 -= carry11 << 21;
|
242
|
+
|
243
|
+
s0 += s12 * 666643;
|
244
|
+
s1 += s12 * 470296;
|
245
|
+
s2 += s12 * 654183;
|
246
|
+
s3 -= s12 * 997805;
|
247
|
+
s4 += s12 * 136657;
|
248
|
+
s5 -= s12 * 683901;
|
249
|
+
// set below
|
250
|
+
//s12 = 0;
|
251
|
+
|
252
|
+
carry0 = s0 >> 21; s1 += carry0; s0 -= carry0 << 21;
|
253
|
+
carry1 = s1 >> 21; s2 += carry1; s1 -= carry1 << 21;
|
254
|
+
carry2 = s2 >> 21; s3 += carry2; s2 -= carry2 << 21;
|
255
|
+
carry3 = s3 >> 21; s4 += carry3; s3 -= carry3 << 21;
|
256
|
+
carry4 = s4 >> 21; s5 += carry4; s4 -= carry4 << 21;
|
257
|
+
carry5 = s5 >> 21; s6 += carry5; s5 -= carry5 << 21;
|
258
|
+
carry6 = s6 >> 21; s7 += carry6; s6 -= carry6 << 21;
|
259
|
+
carry7 = s7 >> 21; s8 += carry7; s7 -= carry7 << 21;
|
260
|
+
carry8 = s8 >> 21; s9 += carry8; s8 -= carry8 << 21;
|
261
|
+
carry9 = s9 >> 21; s10 += carry9; s9 -= carry9 << 21;
|
262
|
+
carry10 = s10 >> 21; s11 += carry10; s10 -= carry10 << 21;
|
263
|
+
//carry11 = s11 >> 21; s12 += carry11; s11 -= carry11 << 21;
|
264
|
+
carry11 = s11 >> 21; s12 = carry11; s11 -= carry11 << 21;
|
265
|
+
|
266
|
+
// TODO-CR BR: Is it really needed to do it TWO times? (it doesn't hurt, just a question).
|
267
|
+
s0 += s12 * 666643;
|
268
|
+
s1 += s12 * 470296;
|
269
|
+
s2 += s12 * 654183;
|
270
|
+
s3 -= s12 * 997805;
|
271
|
+
s4 += s12 * 136657;
|
272
|
+
s5 -= s12 * 683901;
|
273
|
+
// not used again
|
274
|
+
//s12 = 0;
|
275
|
+
|
276
|
+
carry0 = s0 >> 21; s1 += carry0; s0 -= carry0 << 21;
|
277
|
+
carry1 = s1 >> 21; s2 += carry1; s1 -= carry1 << 21;
|
278
|
+
carry2 = s2 >> 21; s3 += carry2; s2 -= carry2 << 21;
|
279
|
+
carry3 = s3 >> 21; s4 += carry3; s3 -= carry3 << 21;
|
280
|
+
carry4 = s4 >> 21; s5 += carry4; s4 -= carry4 << 21;
|
281
|
+
carry5 = s5 >> 21; s6 += carry5; s5 -= carry5 << 21;
|
282
|
+
carry6 = s6 >> 21; s7 += carry6; s6 -= carry6 << 21;
|
283
|
+
carry7 = s7 >> 21; s8 += carry7; s7 -= carry7 << 21;
|
284
|
+
carry8 = s8 >> 21; s9 += carry8; s8 -= carry8 << 21;
|
285
|
+
carry9 = s9 >> 21; s10 += carry9; s9 -= carry9 << 21;
|
286
|
+
carry10 = s10 >> 21; s11 += carry10; s10 -= carry10 << 21;
|
287
|
+
|
288
|
+
// s0, ..., s11 got 21 bits each.
|
289
|
+
byte[] result = new byte[32];
|
290
|
+
result[0] = (byte) s0;
|
291
|
+
result[1] = (byte) (s0 >> 8);
|
292
|
+
result[2] = (byte) ((s0 >> 16) | (s1 << 5));
|
293
|
+
result[3] = (byte) (s1 >> 3);
|
294
|
+
result[4] = (byte) (s1 >> 11);
|
295
|
+
result[5] = (byte) ((s1 >> 19) | (s2 << 2));
|
296
|
+
result[6] = (byte) (s2 >> 6);
|
297
|
+
result[7] = (byte) ((s2 >> 14) | (s3 << 7));
|
298
|
+
result[8] = (byte) (s3 >> 1);
|
299
|
+
result[9] = (byte) (s3 >> 9);
|
300
|
+
result[10] = (byte) ((s3 >> 17) | (s4 << 4));
|
301
|
+
result[11] = (byte) (s4 >> 4);
|
302
|
+
result[12] = (byte) (s4 >> 12);
|
303
|
+
result[13] = (byte) ((s4 >> 20) | (s5 << 1));
|
304
|
+
result[14] = (byte) (s5 >> 7);
|
305
|
+
result[15] = (byte) ((s5 >> 15) | (s6 << 6));
|
306
|
+
result[16] = (byte) (s6 >> 2);
|
307
|
+
result[17] = (byte) (s6 >> 10);
|
308
|
+
result[18] = (byte) ((s6 >> 18) | (s7 << 3));
|
309
|
+
result[19] = (byte) (s7 >> 5);
|
310
|
+
result[20] = (byte) (s7 >> 13);
|
311
|
+
result[21] = (byte) s8;
|
312
|
+
result[22] = (byte) (s8 >> 8);
|
313
|
+
result[23] = (byte) ((s8 >> 16) | (s9 << 5));
|
314
|
+
result[24] = (byte) (s9 >> 3);
|
315
|
+
result[25] = (byte) (s9 >> 11);
|
316
|
+
result[26] = (byte) ((s9 >> 19) | (s10 << 2));
|
317
|
+
result[27] = (byte) (s10 >> 6);
|
318
|
+
result[28] = (byte) ((s10 >> 14) | (s11 << 7));
|
319
|
+
result[29] = (byte) (s11 >> 1);
|
320
|
+
result[30] = (byte) (s11 >> 9);
|
321
|
+
result[31] = (byte) (s11 >> 17);
|
322
|
+
return result;
|
323
|
+
}
|
324
|
+
|
325
|
+
|
326
|
+
/**
|
327
|
+
* $(ab+c) \bmod q$
|
328
|
+
* <p>
|
329
|
+
* Input:
|
330
|
+
* </p><ul>
|
331
|
+
* <li>$a[0]+256*a[1]+\dots+256^{31}*a[31] = a$
|
332
|
+
* <li>$b[0]+256*b[1]+\dots+256^{31}*b[31] = b$
|
333
|
+
* <li>$c[0]+256*c[1]+\dots+256^{31}*c[31] = c$
|
334
|
+
* </ul><p>
|
335
|
+
* Output:
|
336
|
+
* $result[0]+256*result[1]+\dots+256^{31}*result[31] = (ab+c) \bmod q$
|
337
|
+
* where $q = 2^{252} + 27742317777372353535851937790883648493$.
|
338
|
+
* <p>
|
339
|
+
* See the comments in {@link #reduce(byte[])} for an explanation of the algorithm.
|
340
|
+
*/
|
341
|
+
public byte[] multiplyAndAdd(byte[] a, byte[] b, byte[] c) {
|
342
|
+
long a0 = 0x1FFFFF & load_3(a, 0);
|
343
|
+
long a1 = 0x1FFFFF & (load_4(a, 2) >> 5);
|
344
|
+
long a2 = 0x1FFFFF & (load_3(a, 5) >> 2);
|
345
|
+
long a3 = 0x1FFFFF & (load_4(a, 7) >> 7);
|
346
|
+
long a4 = 0x1FFFFF & (load_4(a, 10) >> 4);
|
347
|
+
long a5 = 0x1FFFFF & (load_3(a, 13) >> 1);
|
348
|
+
long a6 = 0x1FFFFF & (load_4(a, 15) >> 6);
|
349
|
+
long a7 = 0x1FFFFF & (load_3(a, 18) >> 3);
|
350
|
+
long a8 = 0x1FFFFF & load_3(a, 21);
|
351
|
+
long a9 = 0x1FFFFF & (load_4(a, 23) >> 5);
|
352
|
+
long a10 = 0x1FFFFF & (load_3(a, 26) >> 2);
|
353
|
+
long a11 = (load_4(a, 28) >> 7);
|
354
|
+
long b0 = 0x1FFFFF & load_3(b, 0);
|
355
|
+
long b1 = 0x1FFFFF & (load_4(b, 2) >> 5);
|
356
|
+
long b2 = 0x1FFFFF & (load_3(b, 5) >> 2);
|
357
|
+
long b3 = 0x1FFFFF & (load_4(b, 7) >> 7);
|
358
|
+
long b4 = 0x1FFFFF & (load_4(b, 10) >> 4);
|
359
|
+
long b5 = 0x1FFFFF & (load_3(b, 13) >> 1);
|
360
|
+
long b6 = 0x1FFFFF & (load_4(b, 15) >> 6);
|
361
|
+
long b7 = 0x1FFFFF & (load_3(b, 18) >> 3);
|
362
|
+
long b8 = 0x1FFFFF & load_3(b, 21);
|
363
|
+
long b9 = 0x1FFFFF & (load_4(b, 23) >> 5);
|
364
|
+
long b10 = 0x1FFFFF & (load_3(b, 26) >> 2);
|
365
|
+
long b11 = (load_4(b, 28) >> 7);
|
366
|
+
long c0 = 0x1FFFFF & load_3(c, 0);
|
367
|
+
long c1 = 0x1FFFFF & (load_4(c, 2) >> 5);
|
368
|
+
long c2 = 0x1FFFFF & (load_3(c, 5) >> 2);
|
369
|
+
long c3 = 0x1FFFFF & (load_4(c, 7) >> 7);
|
370
|
+
long c4 = 0x1FFFFF & (load_4(c, 10) >> 4);
|
371
|
+
long c5 = 0x1FFFFF & (load_3(c, 13) >> 1);
|
372
|
+
long c6 = 0x1FFFFF & (load_4(c, 15) >> 6);
|
373
|
+
long c7 = 0x1FFFFF & (load_3(c, 18) >> 3);
|
374
|
+
long c8 = 0x1FFFFF & load_3(c, 21);
|
375
|
+
long c9 = 0x1FFFFF & (load_4(c, 23) >> 5);
|
376
|
+
long c10 = 0x1FFFFF & (load_3(c, 26) >> 2);
|
377
|
+
long c11 = (load_4(c, 28) >> 7);
|
378
|
+
long s0;
|
379
|
+
long s1;
|
380
|
+
long s2;
|
381
|
+
long s3;
|
382
|
+
long s4;
|
383
|
+
long s5;
|
384
|
+
long s6;
|
385
|
+
long s7;
|
386
|
+
long s8;
|
387
|
+
long s9;
|
388
|
+
long s10;
|
389
|
+
long s11;
|
390
|
+
long s12;
|
391
|
+
long s13;
|
392
|
+
long s14;
|
393
|
+
long s15;
|
394
|
+
long s16;
|
395
|
+
long s17;
|
396
|
+
long s18;
|
397
|
+
long s19;
|
398
|
+
long s20;
|
399
|
+
long s21;
|
400
|
+
long s22;
|
401
|
+
long s23;
|
402
|
+
long carry0;
|
403
|
+
long carry1;
|
404
|
+
long carry2;
|
405
|
+
long carry3;
|
406
|
+
long carry4;
|
407
|
+
long carry5;
|
408
|
+
long carry6;
|
409
|
+
long carry7;
|
410
|
+
long carry8;
|
411
|
+
long carry9;
|
412
|
+
long carry10;
|
413
|
+
long carry11;
|
414
|
+
long carry12;
|
415
|
+
long carry13;
|
416
|
+
long carry14;
|
417
|
+
long carry15;
|
418
|
+
long carry16;
|
419
|
+
long carry17;
|
420
|
+
long carry18;
|
421
|
+
long carry19;
|
422
|
+
long carry20;
|
423
|
+
long carry21;
|
424
|
+
long carry22;
|
425
|
+
|
426
|
+
s0 = c0 + a0*b0;
|
427
|
+
s1 = c1 + a0*b1 + a1*b0;
|
428
|
+
s2 = c2 + a0*b2 + a1*b1 + a2*b0;
|
429
|
+
s3 = c3 + a0*b3 + a1*b2 + a2*b1 + a3*b0;
|
430
|
+
s4 = c4 + a0*b4 + a1*b3 + a2*b2 + a3*b1 + a4*b0;
|
431
|
+
s5 = c5 + a0*b5 + a1*b4 + a2*b3 + a3*b2 + a4*b1 + a5*b0;
|
432
|
+
s6 = c6 + a0*b6 + a1*b5 + a2*b4 + a3*b3 + a4*b2 + a5*b1 + a6*b0;
|
433
|
+
s7 = c7 + a0*b7 + a1*b6 + a2*b5 + a3*b4 + a4*b3 + a5*b2 + a6*b1 + a7*b0;
|
434
|
+
s8 = c8 + a0*b8 + a1*b7 + a2*b6 + a3*b5 + a4*b4 + a5*b3 + a6*b2 + a7*b1 + a8*b0;
|
435
|
+
s9 = c9 + a0*b9 + a1*b8 + a2*b7 + a3*b6 + a4*b5 + a5*b4 + a6*b3 + a7*b2 + a8*b1 + a9*b0;
|
436
|
+
s10 = c10 + a0*b10 + a1*b9 + a2*b8 + a3*b7 + a4*b6 + a5*b5 + a6*b4 + a7*b3 + a8*b2 + a9*b1 + a10*b0;
|
437
|
+
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;
|
438
|
+
s12 = a1*b11 + a2*b10 + a3*b9 + a4*b8 + a5*b7 + a6*b6 + a7*b5 + a8*b4 + a9*b3 + a10*b2 + a11*b1;
|
439
|
+
s13 = a2*b11 + a3*b10 + a4*b9 + a5*b8 + a6*b7 + a7*b6 + a8*b5 + a9*b4 + a10*b3 + a11*b2;
|
440
|
+
s14 = a3*b11 + a4*b10 + a5*b9 + a6*b8 + a7*b7 + a8*b6 + a9*b5 + a10*b4 + a11*b3;
|
441
|
+
s15 = a4*b11 + a5*b10 + a6*b9 + a7*b8 + a8*b7 + a9*b6 + a10*b5 + a11*b4;
|
442
|
+
s16 = a5*b11 + a6*b10 + a7*b9 + a8*b8 + a9*b7 + a10*b6 + a11*b5;
|
443
|
+
s17 = a6*b11 + a7*b10 + a8*b9 + a9*b8 + a10*b7 + a11*b6;
|
444
|
+
s18 = a7*b11 + a8*b10 + a9*b9 + a10*b8 + a11*b7;
|
445
|
+
s19 = a8*b11 + a9*b10 + a10*b9 + a11*b8;
|
446
|
+
s20 = a9*b11 + a10*b10 + a11*b9;
|
447
|
+
s21 = a10*b11 + a11*b10;
|
448
|
+
s22 = a11*b11;
|
449
|
+
// set below
|
450
|
+
//s23 = 0;
|
451
|
+
|
452
|
+
carry0 = (s0 + (1<<20)) >> 21; s1 += carry0; s0 -= carry0 << 21;
|
453
|
+
carry2 = (s2 + (1<<20)) >> 21; s3 += carry2; s2 -= carry2 << 21;
|
454
|
+
carry4 = (s4 + (1<<20)) >> 21; s5 += carry4; s4 -= carry4 << 21;
|
455
|
+
carry6 = (s6 + (1<<20)) >> 21; s7 += carry6; s6 -= carry6 << 21;
|
456
|
+
carry8 = (s8 + (1<<20)) >> 21; s9 += carry8; s8 -= carry8 << 21;
|
457
|
+
carry10 = (s10 + (1<<20)) >> 21; s11 += carry10; s10 -= carry10 << 21;
|
458
|
+
carry12 = (s12 + (1<<20)) >> 21; s13 += carry12; s12 -= carry12 << 21;
|
459
|
+
carry14 = (s14 + (1<<20)) >> 21; s15 += carry14; s14 -= carry14 << 21;
|
460
|
+
carry16 = (s16 + (1<<20)) >> 21; s17 += carry16; s16 -= carry16 << 21;
|
461
|
+
carry18 = (s18 + (1<<20)) >> 21; s19 += carry18; s18 -= carry18 << 21;
|
462
|
+
carry20 = (s20 + (1<<20)) >> 21; s21 += carry20; s20 -= carry20 << 21;
|
463
|
+
//carry22 = (s22 + (1<<20)) >> 21; s23 += carry22; s22 -= carry22 << 21;
|
464
|
+
carry22 = (s22 + (1<<20)) >> 21; s23 = carry22; s22 -= carry22 << 21;
|
465
|
+
|
466
|
+
carry1 = (s1 + (1<<20)) >> 21; s2 += carry1; s1 -= carry1 << 21;
|
467
|
+
carry3 = (s3 + (1<<20)) >> 21; s4 += carry3; s3 -= carry3 << 21;
|
468
|
+
carry5 = (s5 + (1<<20)) >> 21; s6 += carry5; s5 -= carry5 << 21;
|
469
|
+
carry7 = (s7 + (1<<20)) >> 21; s8 += carry7; s7 -= carry7 << 21;
|
470
|
+
carry9 = (s9 + (1<<20)) >> 21; s10 += carry9; s9 -= carry9 << 21;
|
471
|
+
carry11 = (s11 + (1<<20)) >> 21; s12 += carry11; s11 -= carry11 << 21;
|
472
|
+
carry13 = (s13 + (1<<20)) >> 21; s14 += carry13; s13 -= carry13 << 21;
|
473
|
+
carry15 = (s15 + (1<<20)) >> 21; s16 += carry15; s15 -= carry15 << 21;
|
474
|
+
carry17 = (s17 + (1<<20)) >> 21; s18 += carry17; s17 -= carry17 << 21;
|
475
|
+
carry19 = (s19 + (1<<20)) >> 21; s20 += carry19; s19 -= carry19 << 21;
|
476
|
+
carry21 = (s21 + (1<<20)) >> 21; s22 += carry21; s21 -= carry21 << 21;
|
477
|
+
|
478
|
+
s11 += s23 * 666643;
|
479
|
+
s12 += s23 * 470296;
|
480
|
+
s13 += s23 * 654183;
|
481
|
+
s14 -= s23 * 997805;
|
482
|
+
s15 += s23 * 136657;
|
483
|
+
s16 -= s23 * 683901;
|
484
|
+
// not used again
|
485
|
+
//s23 = 0;
|
486
|
+
|
487
|
+
s10 += s22 * 666643;
|
488
|
+
s11 += s22 * 470296;
|
489
|
+
s12 += s22 * 654183;
|
490
|
+
s13 -= s22 * 997805;
|
491
|
+
s14 += s22 * 136657;
|
492
|
+
s15 -= s22 * 683901;
|
493
|
+
// not used again
|
494
|
+
//s22 = 0;
|
495
|
+
|
496
|
+
s9 += s21 * 666643;
|
497
|
+
s10 += s21 * 470296;
|
498
|
+
s11 += s21 * 654183;
|
499
|
+
s12 -= s21 * 997805;
|
500
|
+
s13 += s21 * 136657;
|
501
|
+
s14 -= s21 * 683901;
|
502
|
+
// not used again
|
503
|
+
//s21 = 0;
|
504
|
+
|
505
|
+
s8 += s20 * 666643;
|
506
|
+
s9 += s20 * 470296;
|
507
|
+
s10 += s20 * 654183;
|
508
|
+
s11 -= s20 * 997805;
|
509
|
+
s12 += s20 * 136657;
|
510
|
+
s13 -= s20 * 683901;
|
511
|
+
// not used again
|
512
|
+
//s20 = 0;
|
513
|
+
|
514
|
+
s7 += s19 * 666643;
|
515
|
+
s8 += s19 * 470296;
|
516
|
+
s9 += s19 * 654183;
|
517
|
+
s10 -= s19 * 997805;
|
518
|
+
s11 += s19 * 136657;
|
519
|
+
s12 -= s19 * 683901;
|
520
|
+
// not used again
|
521
|
+
//s19 = 0;
|
522
|
+
|
523
|
+
s6 += s18 * 666643;
|
524
|
+
s7 += s18 * 470296;
|
525
|
+
s8 += s18 * 654183;
|
526
|
+
s9 -= s18 * 997805;
|
527
|
+
s10 += s18 * 136657;
|
528
|
+
s11 -= s18 * 683901;
|
529
|
+
// not used again
|
530
|
+
//s18 = 0;
|
531
|
+
|
532
|
+
carry6 = (s6 + (1<<20)) >> 21; s7 += carry6; s6 -= carry6 << 21;
|
533
|
+
carry8 = (s8 + (1<<20)) >> 21; s9 += carry8; s8 -= carry8 << 21;
|
534
|
+
carry10 = (s10 + (1<<20)) >> 21; s11 += carry10; s10 -= carry10 << 21;
|
535
|
+
carry12 = (s12 + (1<<20)) >> 21; s13 += carry12; s12 -= carry12 << 21;
|
536
|
+
carry14 = (s14 + (1<<20)) >> 21; s15 += carry14; s14 -= carry14 << 21;
|
537
|
+
carry16 = (s16 + (1<<20)) >> 21; s17 += carry16; s16 -= carry16 << 21;
|
538
|
+
|
539
|
+
carry7 = (s7 + (1<<20)) >> 21; s8 += carry7; s7 -= carry7 << 21;
|
540
|
+
carry9 = (s9 + (1<<20)) >> 21; s10 += carry9; s9 -= carry9 << 21;
|
541
|
+
carry11 = (s11 + (1<<20)) >> 21; s12 += carry11; s11 -= carry11 << 21;
|
542
|
+
carry13 = (s13 + (1<<20)) >> 21; s14 += carry13; s13 -= carry13 << 21;
|
543
|
+
carry15 = (s15 + (1<<20)) >> 21; s16 += carry15; s15 -= carry15 << 21;
|
544
|
+
|
545
|
+
s5 += s17 * 666643;
|
546
|
+
s6 += s17 * 470296;
|
547
|
+
s7 += s17 * 654183;
|
548
|
+
s8 -= s17 * 997805;
|
549
|
+
s9 += s17 * 136657;
|
550
|
+
s10 -= s17 * 683901;
|
551
|
+
// not used again
|
552
|
+
//s17 = 0;
|
553
|
+
|
554
|
+
s4 += s16 * 666643;
|
555
|
+
s5 += s16 * 470296;
|
556
|
+
s6 += s16 * 654183;
|
557
|
+
s7 -= s16 * 997805;
|
558
|
+
s8 += s16 * 136657;
|
559
|
+
s9 -= s16 * 683901;
|
560
|
+
// not used again
|
561
|
+
//s16 = 0;
|
562
|
+
|
563
|
+
s3 += s15 * 666643;
|
564
|
+
s4 += s15 * 470296;
|
565
|
+
s5 += s15 * 654183;
|
566
|
+
s6 -= s15 * 997805;
|
567
|
+
s7 += s15 * 136657;
|
568
|
+
s8 -= s15 * 683901;
|
569
|
+
// not used again
|
570
|
+
//s15 = 0;
|
571
|
+
|
572
|
+
s2 += s14 * 666643;
|
573
|
+
s3 += s14 * 470296;
|
574
|
+
s4 += s14 * 654183;
|
575
|
+
s5 -= s14 * 997805;
|
576
|
+
s6 += s14 * 136657;
|
577
|
+
s7 -= s14 * 683901;
|
578
|
+
// not used again
|
579
|
+
//s14 = 0;
|
580
|
+
|
581
|
+
s1 += s13 * 666643;
|
582
|
+
s2 += s13 * 470296;
|
583
|
+
s3 += s13 * 654183;
|
584
|
+
s4 -= s13 * 997805;
|
585
|
+
s5 += s13 * 136657;
|
586
|
+
s6 -= s13 * 683901;
|
587
|
+
// not used again
|
588
|
+
//s13 = 0;
|
589
|
+
|
590
|
+
s0 += s12 * 666643;
|
591
|
+
s1 += s12 * 470296;
|
592
|
+
s2 += s12 * 654183;
|
593
|
+
s3 -= s12 * 997805;
|
594
|
+
s4 += s12 * 136657;
|
595
|
+
s5 -= s12 * 683901;
|
596
|
+
// set below
|
597
|
+
//s12 = 0;
|
598
|
+
|
599
|
+
carry0 = (s0 + (1<<20)) >> 21; s1 += carry0; s0 -= carry0 << 21;
|
600
|
+
carry2 = (s2 + (1<<20)) >> 21; s3 += carry2; s2 -= carry2 << 21;
|
601
|
+
carry4 = (s4 + (1<<20)) >> 21; s5 += carry4; s4 -= carry4 << 21;
|
602
|
+
carry6 = (s6 + (1<<20)) >> 21; s7 += carry6; s6 -= carry6 << 21;
|
603
|
+
carry8 = (s8 + (1<<20)) >> 21; s9 += carry8; s8 -= carry8 << 21;
|
604
|
+
carry10 = (s10 + (1<<20)) >> 21; s11 += carry10; s10 -= carry10 << 21;
|
605
|
+
|
606
|
+
carry1 = (s1 + (1<<20)) >> 21; s2 += carry1; s1 -= carry1 << 21;
|
607
|
+
carry3 = (s3 + (1<<20)) >> 21; s4 += carry3; s3 -= carry3 << 21;
|
608
|
+
carry5 = (s5 + (1<<20)) >> 21; s6 += carry5; s5 -= carry5 << 21;
|
609
|
+
carry7 = (s7 + (1<<20)) >> 21; s8 += carry7; s7 -= carry7 << 21;
|
610
|
+
carry9 = (s9 + (1<<20)) >> 21; s10 += carry9; s9 -= carry9 << 21;
|
611
|
+
//carry11 = (s11 + (1<<20)) >> 21; s12 += carry11; s11 -= carry11 << 21;
|
612
|
+
carry11 = (s11 + (1<<20)) >> 21; s12 = carry11; s11 -= carry11 << 21;
|
613
|
+
|
614
|
+
s0 += s12 * 666643;
|
615
|
+
s1 += s12 * 470296;
|
616
|
+
s2 += s12 * 654183;
|
617
|
+
s3 -= s12 * 997805;
|
618
|
+
s4 += s12 * 136657;
|
619
|
+
s5 -= s12 * 683901;
|
620
|
+
// set below
|
621
|
+
//s12 = 0;
|
622
|
+
|
623
|
+
carry0 = s0 >> 21; s1 += carry0; s0 -= carry0 << 21;
|
624
|
+
carry1 = s1 >> 21; s2 += carry1; s1 -= carry1 << 21;
|
625
|
+
carry2 = s2 >> 21; s3 += carry2; s2 -= carry2 << 21;
|
626
|
+
carry3 = s3 >> 21; s4 += carry3; s3 -= carry3 << 21;
|
627
|
+
carry4 = s4 >> 21; s5 += carry4; s4 -= carry4 << 21;
|
628
|
+
carry5 = s5 >> 21; s6 += carry5; s5 -= carry5 << 21;
|
629
|
+
carry6 = s6 >> 21; s7 += carry6; s6 -= carry6 << 21;
|
630
|
+
carry7 = s7 >> 21; s8 += carry7; s7 -= carry7 << 21;
|
631
|
+
carry8 = s8 >> 21; s9 += carry8; s8 -= carry8 << 21;
|
632
|
+
carry9 = s9 >> 21; s10 += carry9; s9 -= carry9 << 21;
|
633
|
+
carry10 = s10 >> 21; s11 += carry10; s10 -= carry10 << 21;
|
634
|
+
//carry11 = s11 >> 21; s12 += carry11; s11 -= carry11 << 21;
|
635
|
+
carry11 = s11 >> 21; s12 = carry11; s11 -= carry11 << 21;
|
636
|
+
|
637
|
+
s0 += s12 * 666643;
|
638
|
+
s1 += s12 * 470296;
|
639
|
+
s2 += s12 * 654183;
|
640
|
+
s3 -= s12 * 997805;
|
641
|
+
s4 += s12 * 136657;
|
642
|
+
s5 -= s12 * 683901;
|
643
|
+
// not used again
|
644
|
+
//s12 = 0;
|
645
|
+
|
646
|
+
carry0 = s0 >> 21; s1 += carry0; s0 -= carry0 << 21;
|
647
|
+
carry1 = s1 >> 21; s2 += carry1; s1 -= carry1 << 21;
|
648
|
+
carry2 = s2 >> 21; s3 += carry2; s2 -= carry2 << 21;
|
649
|
+
carry3 = s3 >> 21; s4 += carry3; s3 -= carry3 << 21;
|
650
|
+
carry4 = s4 >> 21; s5 += carry4; s4 -= carry4 << 21;
|
651
|
+
carry5 = s5 >> 21; s6 += carry5; s5 -= carry5 << 21;
|
652
|
+
carry6 = s6 >> 21; s7 += carry6; s6 -= carry6 << 21;
|
653
|
+
carry7 = s7 >> 21; s8 += carry7; s7 -= carry7 << 21;
|
654
|
+
carry8 = s8 >> 21; s9 += carry8; s8 -= carry8 << 21;
|
655
|
+
carry9 = s9 >> 21; s10 += carry9; s9 -= carry9 << 21;
|
656
|
+
carry10 = s10 >> 21; s11 += carry10; s10 -= carry10 << 21;
|
657
|
+
|
658
|
+
byte[] result = new byte[32];
|
659
|
+
result[0] = (byte) s0;
|
660
|
+
result[1] = (byte) (s0 >> 8);
|
661
|
+
result[2] = (byte) ((s0 >> 16) | (s1 << 5));
|
662
|
+
result[3] = (byte) (s1 >> 3);
|
663
|
+
result[4] = (byte) (s1 >> 11);
|
664
|
+
result[5] = (byte) ((s1 >> 19) | (s2 << 2));
|
665
|
+
result[6] = (byte) (s2 >> 6);
|
666
|
+
result[7] = (byte) ((s2 >> 14) | (s3 << 7));
|
667
|
+
result[8] = (byte) (s3 >> 1);
|
668
|
+
result[9] = (byte) (s3 >> 9);
|
669
|
+
result[10] = (byte) ((s3 >> 17) | (s4 << 4));
|
670
|
+
result[11] = (byte) (s4 >> 4);
|
671
|
+
result[12] = (byte) (s4 >> 12);
|
672
|
+
result[13] = (byte) ((s4 >> 20) | (s5 << 1));
|
673
|
+
result[14] = (byte) (s5 >> 7);
|
674
|
+
result[15] = (byte) ((s5 >> 15) | (s6 << 6));
|
675
|
+
result[16] = (byte) (s6 >> 2);
|
676
|
+
result[17] = (byte) (s6 >> 10);
|
677
|
+
result[18] = (byte) ((s6 >> 18) | (s7 << 3));
|
678
|
+
result[19] = (byte) (s7 >> 5);
|
679
|
+
result[20] = (byte) (s7 >> 13);
|
680
|
+
result[21] = (byte) s8;
|
681
|
+
result[22] = (byte) (s8 >> 8);
|
682
|
+
result[23] = (byte) ((s8 >> 16) | (s9 << 5));
|
683
|
+
result[24] = (byte) (s9 >> 3);
|
684
|
+
result[25] = (byte) (s9 >> 11);
|
685
|
+
result[26] = (byte) ((s9 >> 19) | (s10 << 2));
|
686
|
+
result[27] = (byte) (s10 >> 6);
|
687
|
+
result[28] = (byte) ((s10 >> 14) | (s11 << 7));
|
688
|
+
result[29] = (byte) (s11 >> 1);
|
689
|
+
result[30] = (byte) (s11 >> 9);
|
690
|
+
result[31] = (byte) (s11 >> 17);
|
691
|
+
return result;
|
692
|
+
}
|
693
|
+
}
|