33#if CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE
34# pragma GCC diagnostic ignored "-Wunused-function"
37#if CRYPTOPP_MSC_VERSION
38# pragma warning(disable: 4244)
42extern const char DONNA64_FNAME[] = __FILE__;
44ANONYMOUS_NAMESPACE_BEGIN
48#if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64)
54ANONYMOUS_NAMESPACE_END
56#if defined(CRYPTOPP_CURVE25519_64BIT)
60ANONYMOUS_NAMESPACE_BEGIN
63using CryptoPP::word64;
64using CryptoPP::GetWord;
65using CryptoPP::PutWord;
66using CryptoPP::LITTLE_ENDIAN_ORDER;
68inline word64 U8TO64_LE(
const byte* p)
70 return GetWord<word64>(
false, LITTLE_ENDIAN_ORDER, p);
73inline void U64TO8_LE(
byte* p, word64 w)
75 PutWord(
false, LITTLE_ENDIAN_ORDER, p, w);
78ANONYMOUS_NAMESPACE_END
80NAMESPACE_BEGIN(CryptoPP)
82NAMESPACE_BEGIN(X25519)
83ANONYMOUS_NAMESPACE_BEGIN
86using CryptoPP::word32;
87using CryptoPP::sword32;
88using CryptoPP::word64;
89using CryptoPP::sword64;
91using CryptoPP::GetBlock;
92using CryptoPP::LittleEndian;
95using namespace CryptoPP::Donna::Arch64;
99curve25519_copy(bignum25519 out,
const bignum25519 in) {
100 out[0] = in[0]; out[1] = in[1];
101 out[2] = in[2]; out[3] = in[3];
107curve25519_add(bignum25519 out,
const bignum25519 a,
const bignum25519 b) {
108 out[0] = a[0] + b[0];
109 out[1] = a[1] + b[1];
110 out[2] = a[2] + b[2];
111 out[3] = a[3] + b[3];
112 out[4] = a[4] + b[4];
117curve25519_sub(bignum25519 out,
const bignum25519 a,
const bignum25519 b) {
118 out[0] = a[0] + two54m152 - b[0];
119 out[1] = a[1] + two54m8 - b[1];
120 out[2] = a[2] + two54m8 - b[2];
121 out[3] = a[3] + two54m8 - b[3];
122 out[4] = a[4] + two54m8 - b[4];
127curve25519_scalar_product(bignum25519 out,
const bignum25519 in,
const word64 scalar) {
131#if defined(CRYPTOPP_WORD128_AVAILABLE)
132 a = ((word128) in[0]) * scalar; out[0] = (word64)a & reduce_mask_51; c = (word64)(a >> 51);
133 a = ((word128) in[1]) * scalar + c; out[1] = (word64)a & reduce_mask_51; c = (word64)(a >> 51);
134 a = ((word128) in[2]) * scalar + c; out[2] = (word64)a & reduce_mask_51; c = (word64)(a >> 51);
135 a = ((word128) in[3]) * scalar + c; out[3] = (word64)a & reduce_mask_51; c = (word64)(a >> 51);
136 a = ((word128) in[4]) * scalar + c; out[4] = (word64)a & reduce_mask_51; c = (word64)(a >> 51);
139 mul64x64_128(a, in[0], scalar) out[0] = lo128(a) & reduce_mask_51; shr128(c, a, 51);
140 mul64x64_128(a, in[1], scalar) add128_64(a, c) out[1] = lo128(a) & reduce_mask_51; shr128(c, a, 51);
141 mul64x64_128(a, in[2], scalar) add128_64(a, c) out[2] = lo128(a) & reduce_mask_51; shr128(c, a, 51);
142 mul64x64_128(a, in[3], scalar) add128_64(a, c) out[3] = lo128(a) & reduce_mask_51; shr128(c, a, 51);
143 mul64x64_128(a, in[4], scalar) add128_64(a, c) out[4] = lo128(a) & reduce_mask_51; shr128(c, a, 51);
150curve25519_mul(bignum25519 out,
const bignum25519 a,
const bignum25519 b) {
151#if !defined(CRYPTOPP_WORD128_AVAILABLE)
155 word64 r0,r1,r2,r3,r4,s0,s1,s2,s3,s4,c;
157 r0 = b[0]; r1 = b[1]; r2 = b[2]; r3 = b[3]; r4 = b[4];
158 s0 = a[0]; s1 = a[1]; s2 = a[2]; s3 = a[3]; s4 = a[4];
160#if defined(CRYPTOPP_WORD128_AVAILABLE)
161 t[0] = ((word128) r0) * s0;
162 t[1] = ((word128) r0) * s1 + ((word128) r1) * s0;
163 t[2] = ((word128) r0) * s2 + ((word128) r2) * s0 + ((word128) r1) * s1;
164 t[3] = ((word128) r0) * s3 + ((word128) r3) * s0 + ((word128) r1) * s2 + ((word128) r2) * s1;
165 t[4] = ((word128) r0) * s4 + ((word128) r4) * s0 + ((word128) r3) * s1 + ((word128) r1) * s3 + ((word128) r2) * s2;
167 mul64x64_128(t[0], r0, s0)
168 mul64x64_128(t[1], r0, s1) mul64x64_128(mul, r1, s0) add128(t[1], mul)
169 mul64x64_128(t[2], r0, s2) mul64x64_128(mul, r2, s0) add128(t[2], mul) mul64x64_128(mul, r1, s1) add128(t[2], mul)
170 mul64x64_128(t[3], r0, s3) mul64x64_128(mul, r3, s0) add128(t[3], mul) mul64x64_128(mul, r1, s2) add128(t[3], mul) mul64x64_128(mul, r2, s1) add128(t[3], mul)
171 mul64x64_128(t[4], r0, s4) mul64x64_128(mul, r4, s0) add128(t[4], mul) mul64x64_128(mul, r3, s1) add128(t[4], mul) mul64x64_128(mul, r1, s3) add128(t[4], mul) mul64x64_128(mul, r2, s2) add128(t[4], mul)
174 r1 *= 19; r2 *= 19; r3 *= 19; r4 *= 19;
176#if defined(CRYPTOPP_WORD128_AVAILABLE)
177 t[0] += ((word128) r4) * s1 + ((word128) r1) * s4 + ((word128) r2) * s3 + ((word128) r3) * s2;
178 t[1] += ((word128) r4) * s2 + ((word128) r2) * s4 + ((word128) r3) * s3;
179 t[2] += ((word128) r4) * s3 + ((word128) r3) * s4;
180 t[3] += ((word128) r4) * s4;
182 mul64x64_128(mul, r4, s1) add128(t[0], mul) mul64x64_128(mul, r1, s4) add128(t[0], mul) mul64x64_128(mul, r2, s3) add128(t[0], mul) mul64x64_128(mul, r3, s2) add128(t[0], mul)
183 mul64x64_128(mul, r4, s2) add128(t[1], mul) mul64x64_128(mul, r2, s4) add128(t[1], mul) mul64x64_128(mul, r3, s3) add128(t[1], mul)
184 mul64x64_128(mul, r4, s3) add128(t[2], mul) mul64x64_128(mul, r3, s4) add128(t[2], mul)
185 mul64x64_128(mul, r4, s4) add128(t[3], mul)
188 r0 = lo128(t[0]) & reduce_mask_51; shr128(c, t[0], 51);
189 add128_64(t[1], c) r1 = lo128(t[1]) & reduce_mask_51; shr128(c, t[1], 51);
190 add128_64(t[2], c) r2 = lo128(t[2]) & reduce_mask_51; shr128(c, t[2], 51);
191 add128_64(t[3], c) r3 = lo128(t[3]) & reduce_mask_51; shr128(c, t[3], 51);
192 add128_64(t[4], c) r4 = lo128(t[4]) & reduce_mask_51; shr128(c, t[4], 51);
193 r0 += c * 19; c = r0 >> 51; r0 = r0 & reduce_mask_51;
196 out[0] = r0; out[1] = r1; out[2] = r2; out[3] = r3; out[4] = r4;
201curve25519_square_times(bignum25519 out,
const bignum25519 in, word64 count) {
202#if !defined(CRYPTOPP_WORD128_AVAILABLE)
206 word64 r0,r1,r2,r3,r4,c;
207 word64 d0,d1,d2,d4,d419;
209 r0 = in[0]; r1 = in[1]; r2 = in[2]; r3 = in[3]; r4 = in[4];
212 d0 = r0 * 2; d1 = r1 * 2;
214 d419 = r4 * 19; d4 = d419 * 2;
216#if defined(CRYPTOPP_WORD128_AVAILABLE)
217 t[0] = ((word128) r0) * r0 + ((word128) d4) * r1 + (((word128) d2) * (r3 ));
218 t[1] = ((word128) d0) * r1 + ((word128) d4) * r2 + (((word128) r3) * (r3 * 19));
219 t[2] = ((word128) d0) * r2 + ((word128) r1) * r1 + (((word128) d4) * (r3 ));
220 t[3] = ((word128) d0) * r3 + ((word128) d1) * r2 + (((word128) r4) * (d419 ));
221 t[4] = ((word128) d0) * r4 + ((word128) d1) * r3 + (((word128) r2) * (r2 ));
223 mul64x64_128(t[0], r0, r0) mul64x64_128(mul, d4, r1) add128(t[0], mul) mul64x64_128(mul, d2, r3) add128(t[0], mul)
224 mul64x64_128(t[1], d0, r1) mul64x64_128(mul, d4, r2) add128(t[1], mul) mul64x64_128(mul, r3, r3 * 19) add128(t[1], mul)
225 mul64x64_128(t[2], d0, r2) mul64x64_128(mul, r1, r1) add128(t[2], mul) mul64x64_128(mul, d4, r3) add128(t[2], mul)
226 mul64x64_128(t[3], d0, r3) mul64x64_128(mul, d1, r2) add128(t[3], mul) mul64x64_128(mul, r4, d419) add128(t[3], mul)
227 mul64x64_128(t[4], d0, r4) mul64x64_128(mul, d1, r3) add128(t[4], mul) mul64x64_128(mul, r2, r2) add128(t[4], mul)
230 r0 = lo128(t[0]) & reduce_mask_51; shr128(c, t[0], 51);
231 add128_64(t[1], c) r1 = lo128(t[1]) & reduce_mask_51; shr128(c, t[1], 51);
232 add128_64(t[2], c) r2 = lo128(t[2]) & reduce_mask_51; shr128(c, t[2], 51);
233 add128_64(t[3], c) r3 = lo128(t[3]) & reduce_mask_51; shr128(c, t[3], 51);
234 add128_64(t[4], c) r4 = lo128(t[4]) & reduce_mask_51; shr128(c, t[4], 51);
235 r0 += c * 19; c = r0 >> 51; r0 = r0 & reduce_mask_51;
239 out[0] = r0; out[1] = r1; out[2] = r2; out[3] = r3; out[4] = r4;
243curve25519_square(bignum25519 out,
const bignum25519 in) {
244#if !defined(CRYPTOPP_WORD128_AVAILABLE)
248 word64 r0,r1,r2,r3,r4,c;
249 word64 d0,d1,d2,d4,d419;
251 r0 = in[0]; r1 = in[1]; r2 = in[2]; r3 = in[3]; r4 = in[4];
253 d0 = r0 * 2; d1 = r1 * 2;
255 d419 = r4 * 19; d4 = d419 * 2;
257#if defined(CRYPTOPP_WORD128_AVAILABLE)
258 t[0] = ((word128) r0) * r0 + ((word128) d4) * r1 + (((word128) d2) * (r3 ));
259 t[1] = ((word128) d0) * r1 + ((word128) d4) * r2 + (((word128) r3) * (r3 * 19));
260 t[2] = ((word128) d0) * r2 + ((word128) r1) * r1 + (((word128) d4) * (r3 ));
261 t[3] = ((word128) d0) * r3 + ((word128) d1) * r2 + (((word128) r4) * (d419 ));
262 t[4] = ((word128) d0) * r4 + ((word128) d1) * r3 + (((word128) r2) * (r2 ));
264 mul64x64_128(t[0], r0, r0) mul64x64_128(mul, d4, r1) add128(t[0], mul) mul64x64_128(mul, d2, r3) add128(t[0], mul)
265 mul64x64_128(t[1], d0, r1) mul64x64_128(mul, d4, r2) add128(t[1], mul) mul64x64_128(mul, r3, r3 * 19) add128(t[1], mul)
266 mul64x64_128(t[2], d0, r2) mul64x64_128(mul, r1, r1) add128(t[2], mul) mul64x64_128(mul, d4, r3) add128(t[2], mul)
267 mul64x64_128(t[3], d0, r3) mul64x64_128(mul, d1, r2) add128(t[3], mul) mul64x64_128(mul, r4, d419) add128(t[3], mul)
268 mul64x64_128(t[4], d0, r4) mul64x64_128(mul, d1, r3) add128(t[4], mul) mul64x64_128(mul, r2, r2) add128(t[4], mul)
271 r0 = lo128(t[0]) & reduce_mask_51; shr128(c, t[0], 51);
272 add128_64(t[1], c) r1 = lo128(t[1]) & reduce_mask_51; shr128(c, t[1], 51);
273 add128_64(t[2], c) r2 = lo128(t[2]) & reduce_mask_51; shr128(c, t[2], 51);
274 add128_64(t[3], c) r3 = lo128(t[3]) & reduce_mask_51; shr128(c, t[3], 51);
275 add128_64(t[4], c) r4 = lo128(t[4]) & reduce_mask_51; shr128(c, t[4], 51);
276 r0 += c * 19; c = r0 >> 51; r0 = r0 & reduce_mask_51;
279 out[0] = r0; out[1] = r1; out[2] = r2; out[3] = r3; out[4] = r4;
284curve25519_expand(bignum25519 out,
const byte *in) {
287 block(x0)(x1)(x2)(x3);
289 out[0] = x0 & reduce_mask_51; x0 = (x0 >> 51) | (x1 << 13);
290 out[1] = x0 & reduce_mask_51; x1 = (x1 >> 38) | (x2 << 26);
291 out[2] = x1 & reduce_mask_51; x2 = (x2 >> 25) | (x3 << 39);
292 out[3] = x2 & reduce_mask_51; x3 = (x3 >> 12);
293 out[4] = x3 & reduce_mask_51;
300curve25519_contract(
byte *out,
const bignum25519 input) {
310 #define curve25519_contract_carry() \
311 t[1] += t[0] >> 51; t[0] &= reduce_mask_51; \
312 t[2] += t[1] >> 51; t[1] &= reduce_mask_51; \
313 t[3] += t[2] >> 51; t[2] &= reduce_mask_51; \
314 t[4] += t[3] >> 51; t[3] &= reduce_mask_51;
316 #define curve25519_contract_carry_full() curve25519_contract_carry() \
317 t[0] += 19 * (t[4] >> 51); t[4] &= reduce_mask_51;
319 #define curve25519_contract_carry_final() curve25519_contract_carry() \
320 t[4] &= reduce_mask_51;
322 curve25519_contract_carry_full()
323 curve25519_contract_carry_full()
328 curve25519_contract_carry_full()
331 t[0] += 0x8000000000000 - 19;
332 t[1] += 0x8000000000000 - 1;
333 t[2] += 0x8000000000000 - 1;
334 t[3] += 0x8000000000000 - 1;
335 t[4] += 0x8000000000000 - 1;
338 curve25519_contract_carry_final()
340 #define write51full(n,shift) \
341 f = ((t[n] >> shift) | (t[n+1] << (51 - shift))); \
342 for (i = 0; i < 8; i++, f >>= 8) *out++ = (byte)f;
343 #define write51(n) write51full(n,13*n)
350 #undef curve25519_contract_carry
351 #undef curve25519_contract_carry_full
352 #undef curve25519_contract_carry_final
361curve25519_swap_conditional(bignum25519 x, bignum25519 qpx, word64 iswap) {
362 const word64 swap = (word64)(-(sword64)iswap);
363 word64 x0,x1,x2,x3,x4;
365 x0 = swap & (x[0] ^ qpx[0]); x[0] ^= x0; qpx[0] ^= x0;
366 x1 = swap & (x[1] ^ qpx[1]); x[1] ^= x1; qpx[1] ^= x1;
367 x2 = swap & (x[2] ^ qpx[2]); x[2] ^= x2; qpx[2] ^= x2;
368 x3 = swap & (x[3] ^ qpx[3]); x[3] ^= x3; qpx[3] ^= x3;
369 x4 = swap & (x[4] ^ qpx[4]); x[4] ^= x4; qpx[4] ^= x4;
377curve25519_pow_two5mtwo0_two250mtwo0(bignum25519 b) {
378 ALIGN(ALIGN_SPEC) bignum25519 t0,c;
381 curve25519_square_times(t0, b, 5);
382 curve25519_mul(b, t0, b);
383 curve25519_square_times(t0, b, 10);
384 curve25519_mul(c, t0, b);
385 curve25519_square_times(t0, c, 20);
386 curve25519_mul(t0, t0, c);
387 curve25519_square_times(t0, t0, 10);
388 curve25519_mul(b, t0, b);
389 curve25519_square_times(t0, b, 50);
390 curve25519_mul(c, t0, b);
391 curve25519_square_times(t0, c, 100);
392 curve25519_mul(t0, t0, c);
393 curve25519_square_times(t0, t0, 50);
394 curve25519_mul(b, t0, b);
401curve25519_recip(bignum25519 out,
const bignum25519 z) {
402 ALIGN(ALIGN_SPEC) bignum25519 a, t0, b;
404 curve25519_square(a, z);
405 curve25519_square_times(t0, a, 2);
406 curve25519_mul(b, t0, z);
407 curve25519_mul(a, b, a);
408 curve25519_square(t0, a);
409 curve25519_mul(b, t0, b);
410 curve25519_pow_two5mtwo0_two250mtwo0(b);
411 curve25519_square_times(b, b, 5);
412 curve25519_mul(out, b, a);
415ANONYMOUS_NAMESPACE_END
422NAMESPACE_BEGIN(CryptoPP)
423NAMESPACE_BEGIN(Donna)
424NAMESPACE_BEGIN(Ed25519)
425ANONYMOUS_NAMESPACE_BEGIN
428using CryptoPP::word32;
429using CryptoPP::sword32;
430using CryptoPP::word64;
431using CryptoPP::sword64;
433using CryptoPP::GetBlock;
434using CryptoPP::LittleEndian;
436using CryptoPP::SHA512;
439using namespace CryptoPP::Donna::Arch64;
443curve25519_copy(bignum25519 out,
const bignum25519 in) {
444 out[0] = in[0]; out[1] = in[1];
445 out[2] = in[2]; out[3] = in[3];
451curve25519_add(bignum25519 out,
const bignum25519 a,
const bignum25519 b) {
452 out[0] = a[0] + b[0]; out[1] = a[1] + b[1];
453 out[2] = a[2] + b[2]; out[3] = a[3] + b[3];
454 out[4] = a[4] + b[4];
459curve25519_add_after_basic(bignum25519 out,
const bignum25519 a,
const bignum25519 b) {
460 out[0] = a[0] + b[0]; out[1] = a[1] + b[1];
461 out[2] = a[2] + b[2]; out[3] = a[3] + b[3];
462 out[4] = a[4] + b[4];
466curve25519_add_reduce(bignum25519 out,
const bignum25519 a,
const bignum25519 b) {
468 out[0] = a[0] + b[0] ; c = (out[0] >> 51); out[0] &= reduce_mask_51;
469 out[1] = a[1] + b[1] + c; c = (out[1] >> 51); out[1] &= reduce_mask_51;
470 out[2] = a[2] + b[2] + c; c = (out[2] >> 51); out[2] &= reduce_mask_51;
471 out[3] = a[3] + b[3] + c; c = (out[3] >> 51); out[3] &= reduce_mask_51;
472 out[4] = a[4] + b[4] + c; c = (out[4] >> 51); out[4] &= reduce_mask_51;
478curve25519_sub(bignum25519 out,
const bignum25519 a,
const bignum25519 b) {
479 out[0] = a[0] + twoP0 - b[0];
480 out[1] = a[1] + twoP1234 - b[1];
481 out[2] = a[2] + twoP1234 - b[2];
482 out[3] = a[3] + twoP1234 - b[3];
483 out[4] = a[4] + twoP1234 - b[4];
488curve25519_sub_after_basic(bignum25519 out,
const bignum25519 a,
const bignum25519 b) {
489 out[0] = a[0] + fourP0 - b[0];
490 out[1] = a[1] + fourP1234 - b[1];
491 out[2] = a[2] + fourP1234 - b[2];
492 out[3] = a[3] + fourP1234 - b[3];
493 out[4] = a[4] + fourP1234 - b[4];
497curve25519_sub_reduce(bignum25519 out,
const bignum25519 a,
const bignum25519 b) {
499 out[0] = a[0] + fourP0 - b[0] ; c = (out[0] >> 51); out[0] &= reduce_mask_51;
500 out[1] = a[1] + fourP1234 - b[1] + c; c = (out[1] >> 51); out[1] &= reduce_mask_51;
501 out[2] = a[2] + fourP1234 - b[2] + c; c = (out[2] >> 51); out[2] &= reduce_mask_51;
502 out[3] = a[3] + fourP1234 - b[3] + c; c = (out[3] >> 51); out[3] &= reduce_mask_51;
503 out[4] = a[4] + fourP1234 - b[4] + c; c = (out[4] >> 51); out[4] &= reduce_mask_51;
509curve25519_neg(bignum25519 out,
const bignum25519 a) {
511 out[0] = twoP0 - a[0] ; c = (out[0] >> 51); out[0] &= reduce_mask_51;
512 out[1] = twoP1234 - a[1] + c; c = (out[1] >> 51); out[1] &= reduce_mask_51;
513 out[2] = twoP1234 - a[2] + c; c = (out[2] >> 51); out[2] &= reduce_mask_51;
514 out[3] = twoP1234 - a[3] + c; c = (out[3] >> 51); out[3] &= reduce_mask_51;
515 out[4] = twoP1234 - a[4] + c; c = (out[4] >> 51); out[4] &= reduce_mask_51;
521curve25519_mul(bignum25519 out,
const bignum25519 in2,
const bignum25519 in) {
522#if !defined(CRYPTOPP_WORD128_AVAILABLE)
526 word64 r0,r1,r2,r3,r4,s0,s1,s2,s3,s4,c;
528 r0 = in[0]; r1 = in[1];
529 r2 = in[2]; r3 = in[3];
532 s0 = in2[0]; s1 = in2[1];
533 s2 = in2[2]; s3 = in2[3];
536#if defined(CRYPTOPP_WORD128_AVAILABLE)
537 t[0] = ((word128) r0) * s0;
538 t[1] = ((word128) r0) * s1 + ((word128) r1) * s0;
539 t[2] = ((word128) r0) * s2 + ((word128) r2) * s0 + ((word128) r1) * s1;
540 t[3] = ((word128) r0) * s3 + ((word128) r3) * s0 + ((word128) r1) * s2 + ((word128) r2) * s1;
541 t[4] = ((word128) r0) * s4 + ((word128) r4) * s0 + ((word128) r3) * s1 + ((word128) r1) * s3 + ((word128) r2) * s2;
543 mul64x64_128(t[0], r0, s0)
544 mul64x64_128(t[1], r0, s1) mul64x64_128(mul, r1, s0) add128(t[1], mul)
545 mul64x64_128(t[2], r0, s2) mul64x64_128(mul, r2, s0) add128(t[2], mul) mul64x64_128(mul, r1, s1) add128(t[2], mul)
546 mul64x64_128(t[3], r0, s3) mul64x64_128(mul, r3, s0) add128(t[3], mul) mul64x64_128(mul, r1, s2) add128(t[3], mul) mul64x64_128(mul, r2, s1) add128(t[3], mul)
547 mul64x64_128(t[4], r0, s4) mul64x64_128(mul, r4, s0) add128(t[4], mul) mul64x64_128(mul, r3, s1) add128(t[4], mul) mul64x64_128(mul, r1, s3) add128(t[4], mul) mul64x64_128(mul, r2, s2) add128(t[4], mul)
553#if defined(CRYPTOPP_WORD128_AVAILABLE)
554 t[0] += ((word128) r4) * s1 + ((word128) r1) * s4 + ((word128) r2) * s3 + ((word128) r3) * s2;
555 t[1] += ((word128) r4) * s2 + ((word128) r2) * s4 + ((word128) r3) * s3;
556 t[2] += ((word128) r4) * s3 + ((word128) r3) * s4;
557 t[3] += ((word128) r4) * s4;
559 mul64x64_128(mul, r4, s1) add128(t[0], mul) mul64x64_128(mul, r1, s4) add128(t[0], mul) mul64x64_128(mul, r2, s3) add128(t[0], mul) mul64x64_128(mul, r3, s2) add128(t[0], mul)
560 mul64x64_128(mul, r4, s2) add128(t[1], mul) mul64x64_128(mul, r2, s4) add128(t[1], mul) mul64x64_128(mul, r3, s3) add128(t[1], mul)
561 mul64x64_128(mul, r4, s3) add128(t[2], mul) mul64x64_128(mul, r3, s4) add128(t[2], mul)
562 mul64x64_128(mul, r4, s4) add128(t[3], mul)
565 r0 = lo128(t[0]) & reduce_mask_51; shr128(c, t[0], 51);
566 add128_64(t[1], c) r1 = lo128(t[1]) & reduce_mask_51; shr128(c, t[1], 51);
567 add128_64(t[2], c) r2 = lo128(t[2]) & reduce_mask_51; shr128(c, t[2], 51);
568 add128_64(t[3], c) r3 = lo128(t[3]) & reduce_mask_51; shr128(c, t[3], 51);
569 add128_64(t[4], c) r4 = lo128(t[4]) & reduce_mask_51; shr128(c, t[4], 51);
570 r0 += c * 19; c = r0 >> 51; r0 = r0 & reduce_mask_51;
573 out[0] = r0; out[1] = r1;
574 out[2] = r2; out[3] = r3;
579curve25519_mul_noinline(bignum25519 out,
const bignum25519 in2,
const bignum25519 in) {
580 curve25519_mul(out, in2, in);
585curve25519_square_times(bignum25519 out,
const bignum25519 in, word64 count) {
586#if !defined(CRYPTOPP_WORD128_AVAILABLE)
590 word64 r0,r1,r2,r3,r4,c;
591 word64 d0,d1,d2,d4,d419;
593 r0 = in[0]; r1 = in[1];
594 r2 = in[2]; r3 = in[3];
604#if defined(CRYPTOPP_WORD128_AVAILABLE)
605 t[0] = ((word128) r0) * r0 + ((word128) d4) * r1 + (((word128) d2) * (r3 ));
606 t[1] = ((word128) d0) * r1 + ((word128) d4) * r2 + (((word128) r3) * (r3 * 19));
607 t[2] = ((word128) d0) * r2 + ((word128) r1) * r1 + (((word128) d4) * (r3 ));
608 t[3] = ((word128) d0) * r3 + ((word128) d1) * r2 + (((word128) r4) * (d419 ));
609 t[4] = ((word128) d0) * r4 + ((word128) d1) * r3 + (((word128) r2) * (r2 ));
611 mul64x64_128(t[0], r0, r0) mul64x64_128(mul, d4, r1) add128(t[0], mul) mul64x64_128(mul, d2, r3) add128(t[0], mul)
612 mul64x64_128(t[1], d0, r1) mul64x64_128(mul, d4, r2) add128(t[1], mul) mul64x64_128(mul, r3, r3 * 19) add128(t[1], mul)
613 mul64x64_128(t[2], d0, r2) mul64x64_128(mul, r1, r1) add128(t[2], mul) mul64x64_128(mul, d4, r3) add128(t[2], mul)
614 mul64x64_128(t[3], d0, r3) mul64x64_128(mul, d1, r2) add128(t[3], mul) mul64x64_128(mul, r4, d419) add128(t[3], mul)
615 mul64x64_128(t[4], d0, r4) mul64x64_128(mul, d1, r3) add128(t[4], mul) mul64x64_128(mul, r2, r2) add128(t[4], mul)
618 r0 = lo128(t[0]) & reduce_mask_51;
619 r1 = lo128(t[1]) & reduce_mask_51; shl128(c, t[0], 13); r1 += c;
620 r2 = lo128(t[2]) & reduce_mask_51; shl128(c, t[1], 13); r2 += c;
621 r3 = lo128(t[3]) & reduce_mask_51; shl128(c, t[2], 13); r3 += c;
622 r4 = lo128(t[4]) & reduce_mask_51; shl128(c, t[3], 13); r4 += c;
623 shl128(c, t[4], 13); r0 += c * 19;
624 c = r0 >> 51; r0 &= reduce_mask_51;
625 r1 += c ; c = r1 >> 51; r1 &= reduce_mask_51;
626 r2 += c ; c = r2 >> 51; r2 &= reduce_mask_51;
627 r3 += c ; c = r3 >> 51; r3 &= reduce_mask_51;
628 r4 += c ; c = r4 >> 51; r4 &= reduce_mask_51;
632 out[0] = r0; out[1] = r1;
633 out[2] = r2; out[3] = r3;
638curve25519_square(bignum25519 out,
const bignum25519 in) {
639#if !defined(CRYPTOPP_WORD128_AVAILABLE)
643 word64 r0,r1,r2,r3,r4,c;
644 word64 d0,d1,d2,d4,d419;
646 r0 = in[0]; r1 = in[1];
647 r2 = in[2]; r3 = in[3];
650 d0 = r0 * 2; d1 = r1 * 2;
655#if defined(CRYPTOPP_WORD128_AVAILABLE)
656 t[0] = ((word128) r0) * r0 + ((word128) d4) * r1 + (((word128) d2) * (r3 ));
657 t[1] = ((word128) d0) * r1 + ((word128) d4) * r2 + (((word128) r3) * (r3 * 19));
658 t[2] = ((word128) d0) * r2 + ((word128) r1) * r1 + (((word128) d4) * (r3 ));
659 t[3] = ((word128) d0) * r3 + ((word128) d1) * r2 + (((word128) r4) * (d419 ));
660 t[4] = ((word128) d0) * r4 + ((word128) d1) * r3 + (((word128) r2) * (r2 ));
662 mul64x64_128(t[0], r0, r0) mul64x64_128(mul, d4, r1) add128(t[0], mul) mul64x64_128(mul, d2, r3) add128(t[0], mul)
663 mul64x64_128(t[1], d0, r1) mul64x64_128(mul, d4, r2) add128(t[1], mul) mul64x64_128(mul, r3, r3 * 19) add128(t[1], mul)
664 mul64x64_128(t[2], d0, r2) mul64x64_128(mul, r1, r1) add128(t[2], mul) mul64x64_128(mul, d4, r3) add128(t[2], mul)
665 mul64x64_128(t[3], d0, r3) mul64x64_128(mul, d1, r2) add128(t[3], mul) mul64x64_128(mul, r4, d419) add128(t[3], mul)
666 mul64x64_128(t[4], d0, r4) mul64x64_128(mul, d1, r3) add128(t[4], mul) mul64x64_128(mul, r2, r2) add128(t[4], mul)
669 r0 = lo128(t[0]) & reduce_mask_51; shr128(c, t[0], 51);
670 add128_64(t[1], c) r1 = lo128(t[1]) & reduce_mask_51; shr128(c, t[1], 51);
671 add128_64(t[2], c) r2 = lo128(t[2]) & reduce_mask_51; shr128(c, t[2], 51);
672 add128_64(t[3], c) r3 = lo128(t[3]) & reduce_mask_51; shr128(c, t[3], 51);
673 add128_64(t[4], c) r4 = lo128(t[4]) & reduce_mask_51; shr128(c, t[4], 51);
674 r0 += c * 19; c = r0 >> 51; r0 = r0 & reduce_mask_51;
677 out[0] = r0; out[1] = r1;
678 out[2] = r2; out[3] = r3;
684curve25519_expand(bignum25519 out,
const byte *in) {
687 block(x0)(x1)(x2)(x3);
689 out[0] = x0 & reduce_mask_51; x0 = (x0 >> 51) | (x1 << 13);
690 out[1] = x0 & reduce_mask_51; x1 = (x1 >> 38) | (x2 << 26);
691 out[2] = x1 & reduce_mask_51; x2 = (x2 >> 25) | (x3 << 39);
692 out[3] = x2 & reduce_mask_51; x3 = (x3 >> 12);
693 out[4] = x3 & reduce_mask_51;
700curve25519_contract(
byte *out,
const bignum25519 input) {
710 #define curve25519_contract_carry() \
711 t[1] += t[0] >> 51; t[0] &= reduce_mask_51; \
712 t[2] += t[1] >> 51; t[1] &= reduce_mask_51; \
713 t[3] += t[2] >> 51; t[2] &= reduce_mask_51; \
714 t[4] += t[3] >> 51; t[3] &= reduce_mask_51;
716 #define curve25519_contract_carry_full() curve25519_contract_carry() \
717 t[0] += 19 * (t[4] >> 51); t[4] &= reduce_mask_51;
719 #define curve25519_contract_carry_final() curve25519_contract_carry() \
720 t[4] &= reduce_mask_51;
722 curve25519_contract_carry_full()
723 curve25519_contract_carry_full()
728 curve25519_contract_carry_full()
731 t[0] += (reduce_mask_51 + 1) - 19;
732 t[1] += (reduce_mask_51 + 1) - 1;
733 t[2] += (reduce_mask_51 + 1) - 1;
734 t[3] += (reduce_mask_51 + 1) - 1;
735 t[4] += (reduce_mask_51 + 1) - 1;
738 curve25519_contract_carry_final()
740 #define write51full(n,shift) \
741 f = ((t[n] >> shift) | (t[n+1] << (51 - shift))); \
742 for (i = 0; i < 8; i++, f >>= 8) *out++ = (byte)f;
743 #define write51(n) write51full(n,13*n)
750#if !defined(ED25519_GCC_64BIT_CHOOSE)
754curve25519_move_conditional_bytes(
byte out[96],
const byte in[96], word64 flag)
759#if defined(__GNUC__) && defined(__x86_64__) && 0
760 const word32 iter = 96/
sizeof(word64);
761 word64* outq =
reinterpret_cast<word64*
>(out);
762 const word64* inq =
reinterpret_cast<const word64*
>(in);
765 __asm__ __volatile__ (
767 "cmpq $0, %[flag] ;\n"
768 "movq %[iter], %%rcx ;\n"
770 " movq (%[idx],%[out]), %[val] ;\n"
771 " cmovnzq (%[idx],%[in]), %[val] ;\n"
772 " movq %[val], (%[idx],%[out]) ;\n"
773 " leaq 8(%[idx]), %[idx] ;\n"
775 : [out]
"+S" (outq), [in]
"+D" (inq),
776 [idx]
"+b" (idx), [val]
"=r" (val)
777 : [flag]
"g" (flag), [iter]
"I" (iter)
778 :
"rcx",
"memory",
"cc"
781 const word64 nb = flag - 1, b = ~nb;
782 const word64 *inq = (
const word64 *)(
const void*)in;
783 word64 *outq = (word64 *)(
void *)out;
784 outq[0] = (outq[0] & nb) | (inq[0] & b);
785 outq[1] = (outq[1] & nb) | (inq[1] & b);
786 outq[2] = (outq[2] & nb) | (inq[2] & b);
787 outq[3] = (outq[3] & nb) | (inq[3] & b);
788 outq[4] = (outq[4] & nb) | (inq[4] & b);
789 outq[5] = (outq[5] & nb) | (inq[5] & b);
790 outq[6] = (outq[6] & nb) | (inq[6] & b);
791 outq[7] = (outq[7] & nb) | (inq[7] & b);
792 outq[8] = (outq[8] & nb) | (inq[8] & b);
793 outq[9] = (outq[9] & nb) | (inq[9] & b);
794 outq[10] = (outq[10] & nb) | (inq[10] & b);
795 outq[11] = (outq[11] & nb) | (inq[11] & b);
801curve25519_swap_conditional(bignum25519 a, bignum25519 b, word64 iswap) {
802 const word64 swap = (word64)(-(sword64)iswap);
803 word64 x0,x1,x2,x3,x4;
805 x0 = swap & (a[0] ^ b[0]); a[0] ^= x0; b[0] ^= x0;
806 x1 = swap & (a[1] ^ b[1]); a[1] ^= x1; b[1] ^= x1;
807 x2 = swap & (a[2] ^ b[2]); a[2] ^= x2; b[2] ^= x2;
808 x3 = swap & (a[3] ^ b[3]); a[3] ^= x3; b[3] ^= x3;
809 x4 = swap & (a[4] ^ b[4]); a[4] ^= x4; b[4] ^= x4;
817ed25519_hash(
byte *hash,
const byte *in,
size_t inlen) {
818 SHA512().CalculateDigest(hash, in, inlen);
822ed25519_extsk(hash_512bits extsk,
const byte sk[32]) {
823 ed25519_hash(extsk, sk, 32);
833 while (stream.read((
char*)block.begin(), block.size()))
834 hash.
Update(block, block.size());
836 std::streamsize rem = stream.gcount();
844ed25519_hram(hash_512bits hram,
const byte RS[64],
const byte pk[32],
const byte *m,
size_t mlen) {
848 hash.Update(m, mlen);
853ed25519_hram(hash_512bits hram,
const byte RS[64],
const byte pk[32], std::istream& stream) {
857 UpdateFromStream(hash, stream);
861bignum256modm_element_t
862lt_modm(bignum256modm_element_t a, bignum256modm_element_t b) {
863 return (a - b) >> 63;
867reduce256_modm(bignum256modm r) {
869 bignum256modm_element_t b = 0, pb, mask;
873 pb += modm_m[0]; b = lt_modm(r[0], pb); t[0] = (r[0] - pb + (b << 56)); pb = b;
874 pb += modm_m[1]; b = lt_modm(r[1], pb); t[1] = (r[1] - pb + (b << 56)); pb = b;
875 pb += modm_m[2]; b = lt_modm(r[2], pb); t[2] = (r[2] - pb + (b << 56)); pb = b;
876 pb += modm_m[3]; b = lt_modm(r[3], pb); t[3] = (r[3] - pb + (b << 56)); pb = b;
877 pb += modm_m[4]; b = lt_modm(r[4], pb); t[4] = (r[4] - pb + (b << 32));
882 r[0] ^= mask & (r[0] ^ t[0]);
883 r[1] ^= mask & (r[1] ^ t[1]);
884 r[2] ^= mask & (r[2] ^ t[2]);
885 r[3] ^= mask & (r[3] ^ t[3]);
886 r[4] ^= mask & (r[4] ^ t[4]);
890barrett_reduce256_modm(bignum256modm r,
const bignum256modm q1,
const bignum256modm r1) {
891 bignum256modm q3, r2;
893 bignum256modm_element_t f, b, pb;
898 mul64x64_128(c, modm_mu[0], q1[3]) mul64x64_128(mul, modm_mu[3], q1[0]) add128(c, mul) mul64x64_128(mul, modm_mu[1], q1[2]) add128(c, mul) mul64x64_128(mul, modm_mu[2], q1[1]) add128(c, mul) shr128(f, c, 56);
899 mul64x64_128(c, modm_mu[0], q1[4]) add128_64(c, f) mul64x64_128(mul, modm_mu[4], q1[0]) add128(c, mul) mul64x64_128(mul, modm_mu[3], q1[1]) add128(c, mul) mul64x64_128(mul, modm_mu[1], q1[3]) add128(c, mul) mul64x64_128(mul, modm_mu[2], q1[2]) add128(c, mul)
900 f = lo128(c); q3[0] = (f >> 40) & 0xffff; shr128(f, c, 56);
901 mul64x64_128(c, modm_mu[4], q1[1]) add128_64(c, f) mul64x64_128(mul, modm_mu[1], q1[4]) add128(c, mul) mul64x64_128(mul, modm_mu[2], q1[3]) add128(c, mul) mul64x64_128(mul, modm_mu[3], q1[2]) add128(c, mul)
902 f = lo128(c); q3[0] |= (f << 16) & 0xffffffffffffff; q3[1] = (f >> 40) & 0xffff; shr128(f, c, 56);
903 mul64x64_128(c, modm_mu[4], q1[2]) add128_64(c, f) mul64x64_128(mul, modm_mu[2], q1[4]) add128(c, mul) mul64x64_128(mul, modm_mu[3], q1[3]) add128(c, mul)
904 f = lo128(c); q3[1] |= (f << 16) & 0xffffffffffffff; q3[2] = (f >> 40) & 0xffff; shr128(f, c, 56);
905 mul64x64_128(c, modm_mu[4], q1[3]) add128_64(c, f) mul64x64_128(mul, modm_mu[3], q1[4]) add128(c, mul)
906 f = lo128(c); q3[2] |= (f << 16) & 0xffffffffffffff; q3[3] = (f >> 40) & 0xffff; shr128(f, c, 56);
907 mul64x64_128(c, modm_mu[4], q1[4]) add128_64(c, f)
908 f = lo128(c); q3[3] |= (f << 16) & 0xffffffffffffff; q3[4] = (f >> 40) & 0xffff; shr128(f, c, 56);
911 mul64x64_128(c, modm_m[0], q3[0])
912 r2[0] = lo128(c) & 0xffffffffffffff; shr128(f, c, 56);
913 mul64x64_128(c, modm_m[0], q3[1]) add128_64(c, f) mul64x64_128(mul, modm_m[1], q3[0]) add128(c, mul)
914 r2[1] = lo128(c) & 0xffffffffffffff; shr128(f, c, 56);
915 mul64x64_128(c, modm_m[0], q3[2]) add128_64(c, f) mul64x64_128(mul, modm_m[2], q3[0]) add128(c, mul) mul64x64_128(mul, modm_m[1], q3[1]) add128(c, mul)
916 r2[2] = lo128(c) & 0xffffffffffffff; shr128(f, c, 56);
917 mul64x64_128(c, modm_m[0], q3[3]) add128_64(c, f) mul64x64_128(mul, modm_m[3], q3[0]) add128(c, mul) mul64x64_128(mul, modm_m[1], q3[2]) add128(c, mul) mul64x64_128(mul, modm_m[2], q3[1]) add128(c, mul)
918 r2[3] = lo128(c) & 0xffffffffffffff; shr128(f, c, 56);
919 mul64x64_128(c, modm_m[0], q3[4]) add128_64(c, f) mul64x64_128(mul, modm_m[4], q3[0]) add128(c, mul) mul64x64_128(mul, modm_m[3], q3[1]) add128(c, mul) mul64x64_128(mul, modm_m[1], q3[3]) add128(c, mul) mul64x64_128(mul, modm_m[2], q3[2]) add128(c, mul)
920 r2[4] = lo128(c) & 0x0000ffffffffff;
923 pb += r2[0]; b = lt_modm(r1[0], pb); r[0] = (r1[0] - pb + (b << 56)); pb = b;
924 pb += r2[1]; b = lt_modm(r1[1], pb); r[1] = (r1[1] - pb + (b << 56)); pb = b;
925 pb += r2[2]; b = lt_modm(r1[2], pb); r[2] = (r1[2] - pb + (b << 56)); pb = b;
926 pb += r2[3]; b = lt_modm(r1[3], pb); r[3] = (r1[3] - pb + (b << 56)); pb = b;
927 pb += r2[4]; b = lt_modm(r1[4], pb); r[4] = (r1[4] - pb + (b << 40));
934add256_modm(bignum256modm r,
const bignum256modm x,
const bignum256modm y) {
935 bignum256modm_element_t c;
937 c = x[0] + y[0]; r[0] = c & 0xffffffffffffff; c >>= 56;
938 c += x[1] + y[1]; r[1] = c & 0xffffffffffffff; c >>= 56;
939 c += x[2] + y[2]; r[2] = c & 0xffffffffffffff; c >>= 56;
940 c += x[3] + y[3]; r[3] = c & 0xffffffffffffff; c >>= 56;
941 c += x[4] + y[4]; r[4] = c;
947mul256_modm(bignum256modm r,
const bignum256modm x,
const bignum256modm y) {
948 bignum256modm q1, r1;
950 bignum256modm_element_t f;
952 mul64x64_128(c, x[0], y[0])
953 f = lo128(c); r1[0] = f & 0xffffffffffffff; shr128(f, c, 56);
954 mul64x64_128(c, x[0], y[1]) add128_64(c, f) mul64x64_128(mul, x[1], y[0]) add128(c, mul)
955 f = lo128(c); r1[1] = f & 0xffffffffffffff; shr128(f, c, 56);
956 mul64x64_128(c, x[0], y[2]) add128_64(c, f) mul64x64_128(mul, x[2], y[0]) add128(c, mul) mul64x64_128(mul, x[1], y[1]) add128(c, mul)
957 f = lo128(c); r1[2] = f & 0xffffffffffffff; shr128(f, c, 56);
958 mul64x64_128(c, x[0], y[3]) add128_64(c, f) mul64x64_128(mul, x[3], y[0]) add128(c, mul) mul64x64_128(mul, x[1], y[2]) add128(c, mul) mul64x64_128(mul, x[2], y[1]) add128(c, mul)
959 f = lo128(c); r1[3] = f & 0xffffffffffffff; shr128(f, c, 56);
960 mul64x64_128(c, x[0], y[4]) add128_64(c, f) mul64x64_128(mul, x[4], y[0]) add128(c, mul) mul64x64_128(mul, x[3], y[1]) add128(c, mul) mul64x64_128(mul, x[1], y[3]) add128(c, mul) mul64x64_128(mul, x[2], y[2]) add128(c, mul)
961 f = lo128(c); r1[4] = f & 0x0000ffffffffff; q1[0] = (f >> 24) & 0xffffffff; shr128(f, c, 56);
962 mul64x64_128(c, x[4], y[1]) add128_64(c, f) mul64x64_128(mul, x[1], y[4]) add128(c, mul) mul64x64_128(mul, x[2], y[3]) add128(c, mul) mul64x64_128(mul, x[3], y[2]) add128(c, mul)
963 f = lo128(c); q1[0] |= (f << 32) & 0xffffffffffffff; q1[1] = (f >> 24) & 0xffffffff; shr128(f, c, 56);
964 mul64x64_128(c, x[4], y[2]) add128_64(c, f) mul64x64_128(mul, x[2], y[4]) add128(c, mul) mul64x64_128(mul, x[3], y[3]) add128(c, mul)
965 f = lo128(c); q1[1] |= (f << 32) & 0xffffffffffffff; q1[2] = (f >> 24) & 0xffffffff; shr128(f, c, 56);
966 mul64x64_128(c, x[4], y[3]) add128_64(c, f) mul64x64_128(mul, x[3], y[4]) add128(c, mul)
967 f = lo128(c); q1[2] |= (f << 32) & 0xffffffffffffff; q1[3] = (f >> 24) & 0xffffffff; shr128(f, c, 56);
968 mul64x64_128(c, x[4], y[4]) add128_64(c, f)
969 f = lo128(c); q1[3] |= (f << 32) & 0xffffffffffffff; q1[4] = (f >> 24) & 0xffffffff; shr128(f, c, 56);
972 barrett_reduce256_modm(r, q1, r1);
976expand256_modm(bignum256modm out,
const byte *in,
size_t len) {
978 bignum256modm_element_t x[16];
981 memcpy(work, in, len);
982 x[0] = U8TO64_LE(work + 0);
983 x[1] = U8TO64_LE(work + 8);
984 x[2] = U8TO64_LE(work + 16);
985 x[3] = U8TO64_LE(work + 24);
986 x[4] = U8TO64_LE(work + 32);
987 x[5] = U8TO64_LE(work + 40);
988 x[6] = U8TO64_LE(work + 48);
989 x[7] = U8TO64_LE(work + 56);
992 out[0] = ( x[0]) & 0xffffffffffffff;
993 out[1] = ((x[ 0] >> 56) | (x[ 1] << 8)) & 0xffffffffffffff;
994 out[2] = ((x[ 1] >> 48) | (x[ 2] << 16)) & 0xffffffffffffff;
995 out[3] = ((x[ 2] >> 40) | (x[ 3] << 24)) & 0xffffffffffffff;
996 out[4] = ((x[ 3] >> 32) | (x[ 4] << 32)) & 0x0000ffffffffff;
1003 q1[0] = ((x[ 3] >> 56) | (x[ 4] << 8)) & 0xffffffffffffff;
1004 q1[1] = ((x[ 4] >> 48) | (x[ 5] << 16)) & 0xffffffffffffff;
1005 q1[2] = ((x[ 5] >> 40) | (x[ 6] << 24)) & 0xffffffffffffff;
1006 q1[3] = ((x[ 6] >> 32) | (x[ 7] << 32)) & 0xffffffffffffff;
1007 q1[4] = ((x[ 7] >> 24) );
1009 barrett_reduce256_modm(out, q1, out);
1013expand_raw256_modm(bignum256modm out,
const byte in[32]) {
1014 bignum256modm_element_t x[4];
1016 x[0] = U8TO64_LE(in + 0);
1017 x[1] = U8TO64_LE(in + 8);
1018 x[2] = U8TO64_LE(in + 16);
1019 x[3] = U8TO64_LE(in + 24);
1021 out[0] = ( x[0]) & 0xffffffffffffff;
1022 out[1] = ((x[ 0] >> 56) | (x[ 1] << 8)) & 0xffffffffffffff;
1023 out[2] = ((x[ 1] >> 48) | (x[ 2] << 16)) & 0xffffffffffffff;
1024 out[3] = ((x[ 2] >> 40) | (x[ 3] << 24)) & 0xffffffffffffff;
1025 out[4] = ((x[ 3] >> 32) ) & 0x000000ffffffff;
1029contract256_modm(
byte out[32],
const bignum256modm in) {
1030 U64TO8_LE(out + 0, (in[0] ) | (in[1] << 56));
1031 U64TO8_LE(out + 8, (in[1] >> 8) | (in[2] << 48));
1032 U64TO8_LE(out + 16, (in[2] >> 16) | (in[3] << 40));
1033 U64TO8_LE(out + 24, (in[3] >> 24) | (in[4] << 32));
1037contract256_window4_modm(
signed char r[64],
const bignum256modm in) {
1039 signed char *quads = r;
1040 bignum256modm_element_t i, j, v, m;
1042 for (i = 0; i < 5; i++) {
1044 m = (i == 4) ? 8 : 14;
1045 for (j = 0; j < m; j++) {
1046 *quads++ = (v & 15);
1053 for(i = 0; i < 63; i++) {
1055 r[i+1] += (r[i] >> 4);
1057 carry = (r[i] >> 3);
1058 r[i] -= (carry << 4);
1064contract256_slidingwindow_modm(
signed char r[256],
const bignum256modm s,
int windowsize) {
1066 int m = (1 << (windowsize - 1)) - 1, soplen = 256;
1067 signed char *bits = r;
1068 bignum256modm_element_t v;
1071 for (i = 0; i < 4; i++) {
1073 for (j = 0; j < 56; j++, v >>= 1)
1077 for (j = 0; j < 32; j++, v >>= 1)
1081 for (j = 0; j < soplen; j++) {
1085 for (b = 1; (b < (soplen - j)) && (b <= 6); b++) {
1086 if ((r[j] + (r[j + b] << b)) <= m) {
1087 r[j] += r[j + b] << b;
1089 }
else if ((r[j] - (r[j + b] << b)) >= -m) {
1090 r[j] -= r[j + b] << b;
1091 for (k = j + b; k < soplen; k++) {
1098 }
else if (r[j + b]) {
1110curve25519_pow_two5mtwo0_two250mtwo0(bignum25519 b) {
1111 ALIGN(ALIGN_SPEC) bignum25519 t0,c;
1114 curve25519_square_times(t0, b, 5);
1115 curve25519_mul_noinline(b, t0, b);
1116 curve25519_square_times(t0, b, 10);
1117 curve25519_mul_noinline(c, t0, b);
1118 curve25519_square_times(t0, c, 20);
1119 curve25519_mul_noinline(t0, t0, c);
1120 curve25519_square_times(t0, t0, 10);
1121 curve25519_mul_noinline(b, t0, b);
1122 curve25519_square_times(t0, b, 50);
1123 curve25519_mul_noinline(c, t0, b);
1124 curve25519_square_times(t0, c, 100);
1125 curve25519_mul_noinline(t0, t0, c);
1126 curve25519_square_times(t0, t0, 50);
1127 curve25519_mul_noinline(b, t0, b);
1134curve25519_recip(bignum25519 out,
const bignum25519 z) {
1135 ALIGN(ALIGN_SPEC) bignum25519 a,t0,b;
1137 curve25519_square_times(a, z, 1);
1138 curve25519_square_times(t0, a, 2);
1139 curve25519_mul_noinline(b, t0, z);
1140 curve25519_mul_noinline(a, b, a);
1141 curve25519_square_times(t0, a, 1);
1142 curve25519_mul_noinline(b, t0, b);
1143 curve25519_pow_two5mtwo0_two250mtwo0(b);
1144 curve25519_square_times(b, b, 5);
1145 curve25519_mul_noinline(out, b, a);
1152curve25519_pow_two252m3(bignum25519 two252m3,
const bignum25519 z) {
1153 ALIGN(ALIGN_SPEC) bignum25519 b,c,t0;
1155 curve25519_square_times(c, z, 1);
1156 curve25519_square_times(t0, c, 2);
1157 curve25519_mul_noinline(b, t0, z);
1158 curve25519_mul_noinline(c, b, c);
1159 curve25519_square_times(t0, c, 1);
1160 curve25519_mul_noinline(b, t0, b);
1161 curve25519_pow_two5mtwo0_two250mtwo0(b);
1162 curve25519_square_times(b, b, 2);
1163 curve25519_mul_noinline(two252m3, b, z);
1168 curve25519_mul(r->x, p->x, p->t);
1169 curve25519_mul(r->y, p->y, p->z);
1170 curve25519_mul(r->z, p->z, p->t);
1175 curve25519_mul(r->x, p->x, p->t);
1176 curve25519_mul(r->y, p->y, p->z);
1177 curve25519_mul(r->z, p->z, p->t);
1178 curve25519_mul(r->t, p->x, p->y);
1183 curve25519_sub(p->ysubx, r->y, r->x);
1184 curve25519_add(p->xaddy, r->y, r->x);
1185 curve25519_copy(p->z, r->z);
1186 curve25519_mul(p->t2d, r->t, ge25519_ec2d);
1191 bignum25519 a,b,c,d,t,u;
1193 curve25519_sub(a, p->y, p->x);
1194 curve25519_add(b, p->y, p->x);
1195 curve25519_sub(t, q->y, q->x);
1196 curve25519_add(u, q->y, q->x);
1197 curve25519_mul(a, a, t);
1198 curve25519_mul(b, b, u);
1199 curve25519_mul(c, p->t, q->t);
1200 curve25519_mul(c, c, ge25519_ec2d);
1201 curve25519_mul(d, p->z, q->z);
1202 curve25519_add(d, d, d);
1203 curve25519_sub(r->x, b, a);
1204 curve25519_add(r->y, b, a);
1205 curve25519_add_after_basic(r->z, d, c);
1206 curve25519_sub_after_basic(r->t, d, c);
1213 curve25519_square(a, p->x);
1214 curve25519_square(b, p->y);
1215 curve25519_square(c, p->z);
1216 curve25519_add_reduce(c, c, c);
1217 curve25519_add(r->x, p->x, p->y);
1218 curve25519_square(r->x, r->x);
1219 curve25519_add(r->y, b, a);
1220 curve25519_sub(r->z, b, a);
1221 curve25519_sub_after_basic(r->x, r->x, r->y);
1222 curve25519_sub_after_basic(r->t, c, r->z);
1227 const bignum25519 *qb = (
const bignum25519 *)q;
1228 bignum25519 *rb = (bignum25519 *)r;
1231 curve25519_sub(a, p->y, p->x);
1232 curve25519_add(b, p->y, p->x);
1233 curve25519_mul(a, a, qb[signbit]);
1234 curve25519_mul(r->x, b, qb[signbit^1]);
1235 curve25519_add(r->y, r->x, a);
1236 curve25519_sub(r->x, r->x, a);
1237 curve25519_mul(c, p->t, q->t2d);
1238 curve25519_add_reduce(r->t, p->z, p->z);
1239 curve25519_copy(r->z, r->t);
1240 curve25519_add(rb[2+signbit], rb[2+signbit], c);
1241 curve25519_sub(rb[2+(signbit^1)], rb[2+(signbit^1)], c);
1246 const bignum25519 *qb = (
const bignum25519 *)q;
1247 bignum25519 *rb = (bignum25519 *)r;
1250 curve25519_sub(a, p->y, p->x);
1251 curve25519_add(b, p->y, p->x);
1252 curve25519_mul(a, a, qb[signbit]);
1253 curve25519_mul(r->x, b, qb[signbit^1]);
1254 curve25519_add(r->y, r->x, a);
1255 curve25519_sub(r->x, r->x, a);
1256 curve25519_mul(c, p->t, q->t2d);
1257 curve25519_mul(r->t, p->z, q->z);
1258 curve25519_add_reduce(r->t, r->t, r->t);
1259 curve25519_copy(r->z, r->t);
1260 curve25519_add(rb[2+signbit], rb[2+signbit], c);
1261 curve25519_sub(rb[2+(signbit^1)], rb[2+(signbit^1)], c);
1267 ge25519_double_p1p1(&t, p);
1268 ge25519_p1p1_to_partial(r, &t);
1274 ge25519_double_p1p1(&t, p);
1275 ge25519_p1p1_to_full(r, &t);
1281 ge25519_add_p1p1(&t, p, q);
1282 ge25519_p1p1_to_full(r, &t);
1287 bignum25519 a,b,c,e,f,g,h;
1289 curve25519_sub(a, r->y, r->x);
1290 curve25519_add(b, r->y, r->x);
1291 curve25519_mul(a, a, q->ysubx);
1292 curve25519_mul(e, b, q->xaddy);
1293 curve25519_add(h, e, a);
1294 curve25519_sub(e, e, a);
1295 curve25519_mul(c, r->t, q->t2d);
1296 curve25519_add(f, r->z, r->z);
1297 curve25519_add_after_basic(g, f, c);
1298 curve25519_sub_after_basic(f, f, c);
1299 curve25519_mul(r->x, e, f);
1300 curve25519_mul(r->y, h, g);
1301 curve25519_mul(r->z, g, f);
1302 curve25519_mul(r->t, e, h);
1307 bignum25519 a,b,c,x,y,z,t;
1309 curve25519_sub(a, p->y, p->x);
1310 curve25519_add(b, p->y, p->x);
1311 curve25519_mul(a, a, q->ysubx);
1312 curve25519_mul(x, b, q->xaddy);
1313 curve25519_add(y, x, a);
1314 curve25519_sub(x, x, a);
1315 curve25519_mul(c, p->t, q->t2d);
1316 curve25519_mul(t, p->z, q->z);
1317 curve25519_add(t, t, t);
1318 curve25519_add_after_basic(z, t, c);
1319 curve25519_sub_after_basic(t, t, c);
1320 curve25519_mul(r->xaddy, x, t);
1321 curve25519_mul(r->ysubx, y, z);
1322 curve25519_mul(r->z, z, t);
1323 curve25519_mul(r->t2d, x, y);
1324 curve25519_copy(y, r->ysubx);
1325 curve25519_sub(r->ysubx, r->ysubx, r->xaddy);
1326 curve25519_add(r->xaddy, r->xaddy, y);
1327 curve25519_mul(r->t2d, r->t2d, ge25519_ec2d);
1331ge25519_pack(
byte r[32],
const ge25519 *p) {
1332 bignum25519 tx, ty, zi;
1334 curve25519_recip(zi, p->z);
1335 curve25519_mul(tx, p->x, zi);
1336 curve25519_mul(ty, p->y, zi);
1337 curve25519_contract(r, ty);
1338 curve25519_contract(parity, tx);
1339 r[31] ^= ((parity[0] & 1) << 7);
1343ed25519_verify(
const byte *x,
const byte *y,
size_t len) {
1344 size_t differentbits = 0;
1346 differentbits |= (*x++ ^ *y++);
1347 return (
int) (1 & ((differentbits - 1) >> 8));
1351ge25519_unpack_negative_vartime(
ge25519 *r,
const byte p[32]) {
1352 const byte zero[32] = {0};
1353 const bignum25519 one = {1};
1354 byte parity = p[31] >> 7;
1356 bignum25519 t, root, num, den, d3;
1358 curve25519_expand(r->y, p);
1359 curve25519_copy(r->z, one);
1360 curve25519_square(num, r->y);
1361 curve25519_mul(den, num, ge25519_ecd);
1362 curve25519_sub_reduce(num, num, r->z);
1363 curve25519_add(den, den, r->z);
1367 curve25519_square(t, den);
1368 curve25519_mul(d3, t, den);
1369 curve25519_square(r->x, d3);
1370 curve25519_mul(r->x, r->x, den);
1371 curve25519_mul(r->x, r->x, num);
1372 curve25519_pow_two252m3(r->x, r->x);
1375 curve25519_mul(r->x, r->x, d3);
1376 curve25519_mul(r->x, r->x, num);
1379 curve25519_square(t, r->x);
1380 curve25519_mul(t, t, den);
1381 curve25519_sub_reduce(root, t, num);
1382 curve25519_contract(check, root);
1383 if (!ed25519_verify(check, zero, 32)) {
1384 curve25519_add_reduce(t, t, num);
1385 curve25519_contract(check, t);
1386 if (!ed25519_verify(check, zero, 32))
1388 curve25519_mul(r->x, r->x, ge25519_sqrtneg1);
1391 curve25519_contract(check, r->x);
1392 if ((check[0] & 1) == parity) {
1393 curve25519_copy(t, r->x);
1394 curve25519_neg(r->x, t);
1396 curve25519_mul(r->t, r->x, r->y);
1402ge25519_double_scalarmult_vartime(
ge25519 *r,
const ge25519 *p1,
const bignum256modm s1,
const bignum256modm s2) {
1403 signed char slide1[256], slide2[256];
1409 contract256_slidingwindow_modm(slide1, s1, S1_SWINDOWSIZE);
1410 contract256_slidingwindow_modm(slide2, s2, S2_SWINDOWSIZE);
1412 ge25519_double(&d1, p1);
1413 ge25519_full_to_pniels(pre1, p1);
1414 for (i = 0; i < S1_TABLE_SIZE - 1; i++)
1415 ge25519_pnielsadd(&pre1[i+1], &d1, &pre1[i]);
1418 memset(r, 0,
sizeof(
ge25519));
1423 while ((i >= 0) && !(slide1[i] | slide2[i]))
1426 for (; i >= 0; i--) {
1427 ge25519_double_p1p1(&t, r);
1430 ge25519_p1p1_to_full(r, &t);
1431 ge25519_pnielsadd_p1p1(&t, r, &pre1[abs(slide1[i]) / 2], (
byte)slide1[i] >> 7);
1435 ge25519_p1p1_to_full(r, &t);
1436 ge25519_nielsadd2_p1p1(&t, r, &ge25519_niels_sliding_multiples[abs(slide2[i]) / 2], (
byte)slide2[i] >> 7);
1439 ge25519_p1p1_to_partial(r, &t);
1443#if !defined(HAVE_GE25519_SCALARMULT_BASE_CHOOSE_NIELS)
1447 return ((b ^ c) - 1) >> 31;
1451ge25519_scalarmult_base_choose_niels(
ge25519_niels *t,
const byte table[256][96],
word32 pos,
signed char b) {
1454 word32 mask = ~(sign - 1);
1455 word32 u = (b + mask) ^ mask;
1459 byte packed[96] = {0};
1463 for (i = 0; i < 8; i++)
1464 curve25519_move_conditional_bytes(packed, table[(pos * 8) + i], ge25519_windowb_equal(u, i + 1));
1467 curve25519_expand(t->ysubx, packed + 0);
1468 curve25519_expand(t->xaddy, packed + 32);
1469 curve25519_expand(t->t2d , packed + 64);
1472 curve25519_swap_conditional(t->ysubx, t->xaddy, sign);
1473 curve25519_neg(neg, t->t2d);
1474 curve25519_swap_conditional(t->t2d, neg, sign);
1481ge25519_scalarmult_base_niels(
ge25519 *r,
const byte basepoint_table[256][96],
const bignum256modm s) {
1486 contract256_window4_modm(b, s);
1488 ge25519_scalarmult_base_choose_niels(&t, basepoint_table, 0, b[1]);
1489 curve25519_sub_reduce(r->x, t.xaddy, t.ysubx);
1490 curve25519_add_reduce(r->y, t.xaddy, t.ysubx);
1491 memset(r->z, 0,
sizeof(bignum25519));
1492 curve25519_copy(r->t, t.t2d);
1494 for (i = 3; i < 64; i += 2) {
1495 ge25519_scalarmult_base_choose_niels(&t, basepoint_table, i / 2, b[i]);
1496 ge25519_nielsadd2(r, &t);
1498 ge25519_double_partial(r, r);
1499 ge25519_double_partial(r, r);
1500 ge25519_double_partial(r, r);
1501 ge25519_double(r, r);
1502 ge25519_scalarmult_base_choose_niels(&t, basepoint_table, 0, b[0]);
1503 curve25519_mul(t.t2d, t.t2d, ge25519_ecd);
1504 ge25519_nielsadd2(r, &t);
1505 for(i = 2; i < 64; i += 2) {
1506 ge25519_scalarmult_base_choose_niels(&t, basepoint_table, i / 2, b[i]);
1507 ge25519_nielsadd2(r, &t);
1511ANONYMOUS_NAMESPACE_END
1518NAMESPACE_BEGIN(CryptoPP)
1519NAMESPACE_BEGIN(Donna)
1521int curve25519_mult_CXX(
byte sharedKey[32],
const byte secretKey[32],
const byte othersKey[32])
1523 using namespace CryptoPP::Donna::X25519;
1526 for (
size_t i = 0;i < 32;++i)
1527 e[i] = secretKey[i];
1528 e[0] &= 0xf8; e[31] &= 0x7f; e[31] |= 0x40;
1530 bignum25519 nqpqx = {1}, nqpqz = {0}, nqz = {1}, nqx;
1531 bignum25519 q, qx, qpqx, qqx, zzz, zmone;
1532 size_t bit, lastbit;
1534 curve25519_expand(q, othersKey);
1535 curve25519_copy(nqx, q);
1542 for (
int i = 253; i >= 2; i--) {
1543 curve25519_add(qx, nqx, nqz);
1544 curve25519_sub(nqz, nqx, nqz);
1545 curve25519_add(qpqx, nqpqx, nqpqz);
1546 curve25519_sub(nqpqz, nqpqx, nqpqz);
1547 curve25519_mul(nqpqx, qpqx, nqz);
1548 curve25519_mul(nqpqz, qx, nqpqz);
1549 curve25519_add(qqx, nqpqx, nqpqz);
1550 curve25519_sub(nqpqz, nqpqx, nqpqz);
1551 curve25519_square(nqpqz, nqpqz);
1552 curve25519_square(nqpqx, qqx);
1553 curve25519_mul(nqpqz, nqpqz, q);
1554 curve25519_square(qx, qx);
1555 curve25519_square(nqz, nqz);
1556 curve25519_mul(nqx, qx, nqz);
1557 curve25519_sub(nqz, qx, nqz);
1558 curve25519_scalar_product(zzz, nqz, 121665);
1559 curve25519_add(zzz, zzz, qx);
1560 curve25519_mul(nqz, nqz, zzz);
1562 bit = (e[i/8] >> (i & 7)) & 1;
1563 curve25519_swap_conditional(nqx, nqpqx, bit ^ lastbit);
1564 curve25519_swap_conditional(nqz, nqpqz, bit ^ lastbit);
1569 for (
int i = 0; i < 3; i++) {
1570 curve25519_add(qx, nqx, nqz);
1571 curve25519_sub(nqz, nqx, nqz);
1572 curve25519_square(qx, qx);
1573 curve25519_square(nqz, nqz);
1574 curve25519_mul(nqx, qx, nqz);
1575 curve25519_sub(nqz, qx, nqz);
1576 curve25519_scalar_product(zzz, nqz, 121665);
1577 curve25519_add(zzz, zzz, qx);
1578 curve25519_mul(nqz, nqz, zzz);
1581 curve25519_recip(zmone, nqz);
1582 curve25519_mul(nqz, nqx, zmone);
1583 curve25519_contract(sharedKey, nqz);
1590 using namespace CryptoPP::Donna::X25519;
1592#if (CRYPTOPP_CURVE25519_SSE2)
1594 return curve25519_mult_SSE2(publicKey, secretKey, basePoint);
1598 return curve25519_mult_CXX(publicKey, secretKey, basePoint);
1601int curve25519_mult(
byte sharedKey[32],
const byte secretKey[32],
const byte othersKey[32])
1603#if (CRYPTOPP_CURVE25519_SSE2)
1605 return curve25519_mult_SSE2(sharedKey, secretKey, othersKey);
1609 return curve25519_mult_CXX(sharedKey, secretKey, othersKey);
1617NAMESPACE_BEGIN(CryptoPP)
1618NAMESPACE_BEGIN(Donna)
1621ed25519_publickey_CXX(
byte publicKey[32],
const byte secretKey[32])
1623 using namespace CryptoPP::Donna::Ed25519;
1630 ed25519_extsk(extsk, secretKey);
1631 expand256_modm(a, extsk, 32);
1632 ge25519_scalarmult_base_niels(&A, ge25519_niels_base_multiples, a);
1633 ge25519_pack(publicKey, &A);
1641 return ed25519_publickey_CXX(publicKey, secretKey);
1645ed25519_sign_CXX(std::istream& stream,
const byte sk[32],
const byte pk[32],
byte RS[64])
1647 using namespace CryptoPP::Donna::Ed25519;
1649 bignum256modm r, S, a;
1651 hash_512bits extsk, hashr, hram;
1657 std::streampos where = stream.tellg();
1659 ed25519_extsk(extsk, sk);
1663 hash.Update(extsk + 32, 32);
1664 UpdateFromStream(hash, stream);
1666 expand256_modm(r, hashr, 64);
1669 ge25519_scalarmult_base_niels(&R, ge25519_niels_base_multiples, r);
1670 ge25519_pack(RS, &R);
1674 stream.seekg(where);
1677 ed25519_hram(hram, RS, pk, stream);
1678 expand256_modm(S, hram, 64);
1681 expand256_modm(a, extsk, 32);
1682 mul256_modm(S, S, a);
1685 add256_modm(S, S, r);
1688 contract256_modm(RS + 32, S);
1693ed25519_sign_CXX(
const byte *m,
size_t mlen,
const byte sk[32],
const byte pk[32],
byte RS[64])
1695 using namespace CryptoPP::Donna::Ed25519;
1697 bignum256modm r, S, a;
1699 hash_512bits extsk, hashr, hram;
1701 ed25519_extsk(extsk, sk);
1705 hash.Update(extsk + 32, 32);
1706 hash.Update(m, mlen);
1708 expand256_modm(r, hashr, 64);
1711 ge25519_scalarmult_base_niels(&R, ge25519_niels_base_multiples, r);
1712 ge25519_pack(RS, &R);
1715 ed25519_hram(hram, RS, pk, m, mlen);
1716 expand256_modm(S, hram, 64);
1719 expand256_modm(a, extsk, 32);
1720 mul256_modm(S, S, a);
1723 add256_modm(S, S, r);
1726 contract256_modm(RS + 32, S);
1731ed25519_sign(std::istream& stream,
const byte secretKey[32],
const byte publicKey[32],
1734 return ed25519_sign_CXX(stream, secretKey, publicKey, signature);
1738ed25519_sign(
const byte* message,
size_t messageLength,
const byte secretKey[32],
1739 const byte publicKey[32],
byte signature[64])
1741 return ed25519_sign_CXX(message, messageLength, secretKey, publicKey, signature);
1745ed25519_sign_open_CXX(
const byte *m,
size_t mlen,
const byte pk[32],
const byte RS[64]) {
1747 using namespace CryptoPP::Donna::Ed25519;
1749 ALIGN(ALIGN_SPEC)
ge25519 R, A;
1751 bignum256modm hram, S;
1754 if ((RS[63] & 224) || !ge25519_unpack_negative_vartime(&A, pk))
1758 ed25519_hram(hash, RS, pk, m, mlen);
1759 expand256_modm(hram, hash, 64);
1762 expand256_modm(S, RS + 32, 32);
1765 ge25519_double_scalarmult_vartime(&R, &A, hram, S);
1766 ge25519_pack(checkR, &R);
1769 return ed25519_verify(RS, checkR, 32) ? 0 : -1;
1773ed25519_sign_open_CXX(std::istream& stream,
const byte pk[32],
const byte RS[64]) {
1775 using namespace CryptoPP::Donna::Ed25519;
1777 ALIGN(ALIGN_SPEC)
ge25519 R, A;
1779 bignum256modm hram, S;
1782 if ((RS[63] & 224) || !ge25519_unpack_negative_vartime(&A, pk))
1786 ed25519_hram(hash, RS, pk, stream);
1787 expand256_modm(hram, hash, 64);
1790 expand256_modm(S, RS + 32, 32);
1793 ge25519_double_scalarmult_vartime(&R, &A, hram, S);
1794 ge25519_pack(checkR, &R);
1797 return ed25519_verify(RS, checkR, 32) ? 0 : -1;
1801ed25519_sign_open(std::istream& stream,
const byte publicKey[32],
const byte signature[64])
1803 return ed25519_sign_open_CXX(stream, publicKey, signature);
1807ed25519_sign_open(
const byte *message,
size_t messageLength,
const byte publicKey[32],
const byte signature[64])
1809 return ed25519_sign_open_CXX(message, messageLength, publicKey, signature);
Fixed size stack-based SecBlock.
Access a block of memory.
Library configuration file.
signed int sword32
32-bit signed datatype
unsigned int word32
32-bit unsigned datatype
Functions for CPU features and intrinsics.
int ed25519_sign_open(const byte *message, size_t messageLength, const byte publicKey[32], const byte signature[64])
Verifies a signature on a message.
int ed25519_sign(const byte *message, size_t messageLength, const byte secretKey[32], const byte publicKey[32], byte signature[64])
Creates a signature on a message.
int ed25519_publickey(byte publicKey[32], const byte secretKey[32])
Creates a public key from a secret key.
int curve25519_mult(byte publicKey[32], const byte secretKey[32])
Generate a public key.
Utility functions for the Crypto++ library.
void PutWord(bool assumeAligned, ByteOrder order, byte *block, T value, const byte *xorBlock=NULLPTR)
Access a block of memory.
Classes and functions for secure memory allocations.
Classes for SHA-1 and SHA-2 family of message digests.