├── .gitignore ├── LICENSE ├── MANIFEST.in ├── README.md ├── curve ├── curve25519-donna.c ├── curve25519-donna.h └── ed25519 │ ├── additions │ ├── compare.c │ ├── compare.h │ ├── crypto_additions.h │ ├── crypto_hash_sha512.h │ ├── curve_sigs.c │ ├── curve_sigs.h │ ├── elligator.c │ ├── fe_isequal.c │ ├── fe_isreduced.c │ ├── fe_mont_rhs.c │ ├── fe_montx_to_edy.c │ ├── fe_sqrt.c │ ├── ge_isneutral.c │ ├── ge_montx_to_p3.c │ ├── ge_neg.c │ ├── ge_p3_to_montx.c │ ├── ge_scalarmult.c │ ├── ge_scalarmult_cofactor.c │ ├── generalized │ │ ├── ge_p3_add.c │ │ ├── gen_constants.h │ │ ├── gen_crypto_additions.h │ │ ├── gen_eddsa.c │ │ ├── gen_eddsa.h │ │ ├── gen_labelset.c │ │ ├── gen_labelset.h │ │ ├── gen_veddsa.c │ │ ├── gen_veddsa.h │ │ ├── gen_x.c │ │ ├── gen_x.h │ │ ├── point_isreduced.c │ │ └── sc_isreduced.c │ ├── keygen.c │ ├── keygen.h │ ├── open_modified.c │ ├── sc_clamp.c │ ├── sc_cmov.c │ ├── sc_neg.c │ ├── sign_modified.c │ ├── utility.c │ ├── utility.h │ ├── xeddsa.c │ ├── xeddsa.h │ ├── zeroize.c │ └── zeroize.h │ ├── api.h │ ├── base.h │ ├── base2.h │ ├── d.h │ ├── d2.h │ ├── fe.h │ ├── fe_0.c │ ├── fe_1.c │ ├── fe_add.c │ ├── fe_cmov.c │ ├── fe_copy.c │ ├── fe_frombytes.c │ ├── fe_invert.c │ ├── fe_isnegative.c │ ├── fe_isnonzero.c │ ├── fe_mul.c │ ├── fe_neg.c │ ├── fe_pow22523.c │ ├── fe_sq.c │ ├── fe_sq2.c │ ├── fe_sub.c │ ├── fe_tobytes.c │ ├── ge.h │ ├── ge_add.c │ ├── ge_add.h │ ├── ge_double_scalarmult.c │ ├── ge_frombytes.c │ ├── ge_madd.c │ ├── ge_madd.h │ ├── ge_msub.c │ ├── ge_msub.h │ ├── ge_p1p1_to_p2.c │ ├── ge_p1p1_to_p3.c │ ├── ge_p2_0.c │ ├── ge_p2_dbl.c │ ├── ge_p2_dbl.h │ ├── ge_p3_0.c │ ├── ge_p3_dbl.c │ ├── ge_p3_to_cached.c │ ├── ge_p3_to_p2.c │ ├── ge_p3_tobytes.c │ ├── ge_precomp_0.c │ ├── ge_scalarmult_base.c │ ├── ge_sub.c │ ├── ge_sub.h │ ├── ge_tobytes.c │ ├── main │ └── main.c │ ├── nacl_includes │ ├── crypto_int32.h │ ├── crypto_int64.h │ ├── crypto_sign.h │ ├── crypto_sign_edwards25519sha512batch.h │ ├── crypto_uint32.h │ ├── crypto_uint64.h │ └── crypto_verify_32.h │ ├── nacl_sha512 │ ├── blocks.c │ └── hash.c │ ├── open.c │ ├── pow22523.h │ ├── pow225521.h │ ├── sc.h │ ├── sc_muladd.c │ ├── sc_reduce.c │ ├── sign.c │ ├── sqrtm1.h │ └── tests │ ├── internal_fast_tests.c │ ├── internal_fast_tests.h │ ├── internal_slow_tests.c │ └── internal_slow_tests.h ├── curve25519module.c └── setup.py /.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | dist 3 | *.pyc 4 | *.o 5 | *.egg-info 6 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include curve/curve25519-donna.h 2 | include curve/ed25519/api.h 3 | include curve/ed25519/base.h 4 | include curve/ed25519/base2.h 5 | include curve/ed25519/d.h 6 | include curve/ed25519/d2.h 7 | include curve/ed25519/fe.h 8 | include curve/ed25519/ge.h 9 | include curve/ed25519/ge_add.h 10 | include curve/ed25519/ge_madd.h 11 | include curve/ed25519/ge_msub.h 12 | include curve/ed25519/ge_p2_dbl.h 13 | include curve/ed25519/ge_sub.h 14 | include curve/ed25519/pow22523.h 15 | include curve/ed25519/pow225521.h 16 | include curve/ed25519/sc.h 17 | include curve/ed25519/sqrtm1.h 18 | 19 | include curve/ed25519/additions/compare.h 20 | include curve/ed25519/additions/crypto_additions.h 21 | include curve/ed25519/additions/crypto_hash_sha512.h 22 | include curve/ed25519/additions/curve_sigs.h 23 | include curve/ed25519/additions/keygen.h 24 | include curve/ed25519/additions/utility.h 25 | include curve/ed25519/additions/xeddsa.h 26 | include curve/ed25519/additions/zeroize.h 27 | 28 | include curve/ed25519/nacl_includes/crypto_int32.h 29 | include curve/ed25519/nacl_includes/crypto_int64.h 30 | include curve/ed25519/nacl_includes/crypto_sign.h 31 | include curve/ed25519/nacl_includes/crypto_sign_edwards25519sha512batch.h 32 | include curve/ed25519/nacl_includes/crypto_uint32.h 33 | include curve/ed25519/nacl_includes/crypto_uint64.h 34 | include curve/ed25519/nacl_includes/crypto_verify_32.h 35 | 36 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | This is python wrapper for curve25519 library with ed25519 signatures. The C code was pulled from [libaxolotl-android](https://github.com/WhisperSystems/libaxolotl-android) 2 | At the moment this wrapper is meant for use by [python-axolotl](http://github.com/tgalal/python-axolotl) and provides the following methods only: 3 | 4 | ```python 5 | import axolotl_curve25519 as curve 6 | import os 7 | 8 | randm32 = os.urandom(32) 9 | randm64 = os.urandom(64) 10 | 11 | private_key = curve.generatePrivateKey(randm32) 12 | public_key = message = curve.generatePublicKey(private_key) 13 | 14 | agreement = curve.calculateAgreement(private_key, public_key) 15 | signature = curve.calculateSignature(randm64, private_key, message) 16 | verified = curve.verifySignature(public_key, message, signature) == 0 17 | ``` 18 | 19 | # Installation 20 | 21 | ## Linux 22 | 23 | You need to have python headers installed, usually through installing package called python-dev, then as superuser run: 24 | ``` 25 | python setup.py install 26 | ``` 27 | 28 | ## Windows 29 | 30 | - Install [mingw](http://www.mingw.org/) compiler 31 | - Add mingw to your PATH 32 | - In PYTHONPATH\Lib\distutils create a file called distutils.cfg and add these lines: 33 | 34 | ``` 35 | [build] 36 | compiler=mingw32 37 | ``` 38 | 39 | - Install gcc: ```mingw-get.exe install gcc``` 40 | - Install zlib [zlib](http://www.zlib.net/) 41 | - ```python setup.py install``` 42 | 43 | 44 | -------------------------------------------------------------------------------- /curve/curve25519-donna.h: -------------------------------------------------------------------------------- 1 | #ifndef CURVE25519_DONNA_H 2 | #define CURVE25519_DONNA_H 3 | 4 | extern int curve25519_donna(uint8_t *, const uint8_t *, const uint8_t *); 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /curve/ed25519/additions/compare.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "compare.h" 3 | 4 | /* Const-time comparison from SUPERCOP, but here it's only used for 5 | signature verification, so doesn't need to be const-time. But 6 | copied the nacl version anyways. */ 7 | int crypto_verify_32_ref(const unsigned char *x, const unsigned char *y) 8 | { 9 | unsigned int differentbits = 0; 10 | #define F(i) differentbits |= x[i] ^ y[i]; 11 | F(0) 12 | F(1) 13 | F(2) 14 | F(3) 15 | F(4) 16 | F(5) 17 | F(6) 18 | F(7) 19 | F(8) 20 | F(9) 21 | F(10) 22 | F(11) 23 | F(12) 24 | F(13) 25 | F(14) 26 | F(15) 27 | F(16) 28 | F(17) 29 | F(18) 30 | F(19) 31 | F(20) 32 | F(21) 33 | F(22) 34 | F(23) 35 | F(24) 36 | F(25) 37 | F(26) 38 | F(27) 39 | F(28) 40 | F(29) 41 | F(30) 42 | F(31) 43 | return (1 & ((differentbits - 1) >> 8)) - 1; 44 | } 45 | -------------------------------------------------------------------------------- /curve/ed25519/additions/compare.h: -------------------------------------------------------------------------------- 1 | #ifndef __COMPARE_H__ 2 | #define __COMPARE_H__ 3 | 4 | int crypto_verify_32_ref(const unsigned char *b1, const unsigned char *b2); 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /curve/ed25519/additions/crypto_additions.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef __CRYPTO_ADDITIONS__ 3 | #define __CRYPTO_ADDITIONS__ 4 | 5 | #include "crypto_uint32.h" 6 | #include "fe.h" 7 | #include "ge.h" 8 | 9 | #define MAX_MSG_LEN 256 10 | 11 | void sc_neg(unsigned char *b, const unsigned char *a); 12 | void sc_cmov(unsigned char* f, const unsigned char* g, unsigned char b); 13 | 14 | int fe_isequal(const fe f, const fe g); 15 | int fe_isreduced(const unsigned char* s); 16 | void fe_mont_rhs(fe v2, const fe u); 17 | void fe_montx_to_edy(fe y, const fe u); 18 | void fe_sqrt(fe b, const fe a); 19 | 20 | int ge_isneutral(const ge_p3* q); 21 | void ge_neg(ge_p3* r, const ge_p3 *p); 22 | void ge_montx_to_p3(ge_p3* p, const fe u, const unsigned char ed_sign_bit); 23 | void ge_p3_to_montx(fe u, const ge_p3 *p); 24 | void ge_scalarmult(ge_p3 *h, const unsigned char *a, const ge_p3 *A); 25 | void ge_scalarmult_cofactor(ge_p3 *q, const ge_p3 *p); 26 | 27 | void elligator(fe u, const fe r); 28 | void hash_to_point(ge_p3* p, const unsigned char* msg, const unsigned long in_len); 29 | 30 | int crypto_sign_modified( 31 | unsigned char *sm, 32 | const unsigned char *m,unsigned long long mlen, 33 | const unsigned char *sk, /* Curve/Ed25519 private key */ 34 | const unsigned char *pk, /* Ed25519 public key */ 35 | const unsigned char *random /* 64 bytes random to hash into nonce */ 36 | ); 37 | 38 | int crypto_sign_open_modified( 39 | unsigned char *m, 40 | const unsigned char *sm,unsigned long long smlen, 41 | const unsigned char *pk 42 | ); 43 | 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /curve/ed25519/additions/crypto_hash_sha512.h: -------------------------------------------------------------------------------- 1 | #ifndef crypto_hash_sha512_H 2 | #define crypto_hash_sha512_H 3 | 4 | extern int crypto_hash_sha512(unsigned char *,const unsigned char *,unsigned long long); 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /curve/ed25519/additions/curve_sigs.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "ge.h" 4 | #include "curve_sigs.h" 5 | #include "crypto_sign.h" 6 | #include "crypto_additions.h" 7 | 8 | int curve25519_sign(unsigned char* signature_out, 9 | const unsigned char* curve25519_privkey, 10 | const unsigned char* msg, const unsigned long msg_len, 11 | const unsigned char* random) 12 | { 13 | ge_p3 ed_pubkey_point; /* Ed25519 pubkey point */ 14 | unsigned char ed_pubkey[32]; /* Ed25519 encoded pubkey */ 15 | unsigned char *sigbuf; /* working buffer */ 16 | unsigned char sign_bit = 0; 17 | 18 | if ((sigbuf = malloc(msg_len + 128)) == 0) { 19 | memset(signature_out, 0, 64); 20 | return -1; 21 | } 22 | 23 | /* Convert the Curve25519 privkey to an Ed25519 public key */ 24 | ge_scalarmult_base(&ed_pubkey_point, curve25519_privkey); 25 | ge_p3_tobytes(ed_pubkey, &ed_pubkey_point); 26 | sign_bit = ed_pubkey[31] & 0x80; 27 | 28 | /* Perform an Ed25519 signature with explicit private key */ 29 | crypto_sign_modified(sigbuf, msg, msg_len, curve25519_privkey, 30 | ed_pubkey, random); 31 | memmove(signature_out, sigbuf, 64); 32 | 33 | /* Encode the sign bit into signature (in unused high bit of S) */ 34 | signature_out[63] &= 0x7F; /* bit should be zero already, but just in case */ 35 | signature_out[63] |= sign_bit; 36 | 37 | free(sigbuf); 38 | return 0; 39 | } 40 | 41 | int curve25519_verify(const unsigned char* signature, 42 | const unsigned char* curve25519_pubkey, 43 | const unsigned char* msg, const unsigned long msg_len) 44 | { 45 | fe u; 46 | fe y; 47 | unsigned char ed_pubkey[32]; 48 | unsigned char *verifybuf = NULL; /* working buffer */ 49 | unsigned char *verifybuf2 = NULL; /* working buffer #2 */ 50 | int result; 51 | 52 | if ((verifybuf = malloc(msg_len + 64)) == 0) { 53 | result = -1; 54 | goto err; 55 | } 56 | 57 | if ((verifybuf2 = malloc(msg_len + 64)) == 0) { 58 | result = -1; 59 | goto err; 60 | } 61 | 62 | /* Convert the Curve25519 public key into an Ed25519 public key. In 63 | particular, convert Curve25519's "montgomery" x-coordinate (u) into an 64 | Ed25519 "edwards" y-coordinate: 65 | 66 | y = (u - 1) / (u + 1) 67 | 68 | NOTE: u=-1 is converted to y=0 since fe_invert is mod-exp 69 | 70 | Then move the sign bit into the pubkey from the signature. 71 | */ 72 | fe_frombytes(u, curve25519_pubkey); 73 | fe_montx_to_edy(y, u); 74 | fe_tobytes(ed_pubkey, y); 75 | 76 | /* Copy the sign bit, and remove it from signature */ 77 | ed_pubkey[31] &= 0x7F; /* bit should be zero already, but just in case */ 78 | ed_pubkey[31] |= (signature[63] & 0x80); 79 | memmove(verifybuf, signature, 64); 80 | verifybuf[63] &= 0x7F; 81 | 82 | memmove(verifybuf+64, msg, msg_len); 83 | 84 | /* Then perform a normal Ed25519 verification, return 0 on success */ 85 | /* The below call has a strange API: */ 86 | /* verifybuf = R || S || message */ 87 | /* verifybuf2 = internal to next call gets a copy of verifybuf, S gets 88 | replaced with pubkey for hashing */ 89 | result = crypto_sign_open_modified(verifybuf2, verifybuf, 64 + msg_len, ed_pubkey); 90 | 91 | err: 92 | 93 | if (verifybuf != NULL) { 94 | free(verifybuf); 95 | } 96 | 97 | if (verifybuf2 != NULL) { 98 | free(verifybuf2); 99 | } 100 | 101 | return result; 102 | } 103 | -------------------------------------------------------------------------------- /curve/ed25519/additions/curve_sigs.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef __CURVE_SIGS_H__ 3 | #define __CURVE_SIGS_H__ 4 | 5 | /* returns 0 on success */ 6 | int curve25519_sign(unsigned char* signature_out, /* 64 bytes */ 7 | const unsigned char* curve25519_privkey, /* 32 bytes */ 8 | const unsigned char* msg, const unsigned long msg_len, /* <= 256 bytes */ 9 | const unsigned char* random); /* 64 bytes */ 10 | 11 | /* returns 0 on success */ 12 | int curve25519_verify(const unsigned char* signature, /* 64 bytes */ 13 | const unsigned char* curve25519_pubkey, /* 32 bytes */ 14 | const unsigned char* msg, const unsigned long msg_len); /* <= 256 bytes */ 15 | 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /curve/ed25519/additions/elligator.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "fe.h" 3 | #include "ge.h" 4 | #include "crypto_uint32.h" 5 | #include "crypto_hash_sha512.h" 6 | #include "crypto_additions.h" 7 | 8 | unsigned int legendre_is_nonsquare(fe in) 9 | { 10 | fe temp; 11 | unsigned char bytes[32]; 12 | fe_pow22523(temp, in); /* temp = in^((q-5)/8) */ 13 | fe_sq(temp, temp); /* in^((q-5)/4) */ 14 | fe_sq(temp, temp); /* in^((q-5)/2) */ 15 | fe_mul(temp, temp, in); /* in^((q-3)/2) */ 16 | fe_mul(temp, temp, in); /* in^((q-1)/2) */ 17 | 18 | /* temp is now the Legendre symbol: 19 | * 1 = square 20 | * 0 = input is zero 21 | * -1 = nonsquare 22 | */ 23 | fe_tobytes(bytes, temp); 24 | return 1 & bytes[31]; 25 | } 26 | 27 | void elligator(fe u, const fe r) 28 | { 29 | /* r = input 30 | * x = -A/(1+2r^2) # 2 is nonsquare 31 | * e = (x^3 + Ax^2 + x)^((q-1)/2) # legendre symbol 32 | * if e == 1 (square) or e == 0 (because x == 0 and 2r^2 + 1 == 0) 33 | * u = x 34 | * if e == -1 (nonsquare) 35 | * u = -x - A 36 | */ 37 | fe A, one, twor2, twor2plus1, twor2plus1inv; 38 | fe x, e, Atemp, uneg; 39 | unsigned int nonsquare; 40 | 41 | fe_1(one); 42 | fe_0(A); 43 | A[0] = 486662; /* A = 486662 */ 44 | 45 | fe_sq2(twor2, r); /* 2r^2 */ 46 | fe_add(twor2plus1, twor2, one); /* 1+2r^2 */ 47 | fe_invert(twor2plus1inv, twor2plus1); /* 1/(1+2r^2) */ 48 | fe_mul(x, twor2plus1inv, A); /* A/(1+2r^2) */ 49 | fe_neg(x, x); /* x = -A/(1+2r^2) */ 50 | 51 | fe_mont_rhs(e, x); /* e = x^3 + Ax^2 + x */ 52 | nonsquare = legendre_is_nonsquare(e); 53 | 54 | fe_0(Atemp); 55 | fe_cmov(Atemp, A, nonsquare); /* 0, or A if nonsquare */ 56 | fe_add(u, x, Atemp); /* x, or x+A if nonsquare */ 57 | fe_neg(uneg, u); /* -x, or -x-A if nonsquare */ 58 | fe_cmov(u, uneg, nonsquare); /* x, or -x-A if nonsquare */ 59 | } 60 | 61 | void hash_to_point(ge_p3* p, const unsigned char* in, const unsigned long in_len) 62 | { 63 | unsigned char hash[64]; 64 | fe h, u; 65 | unsigned char sign_bit; 66 | ge_p3 p3; 67 | 68 | crypto_hash_sha512(hash, in, in_len); 69 | 70 | /* take the high bit as Edwards sign bit */ 71 | sign_bit = (hash[31] & 0x80) >> 7; 72 | hash[31] &= 0x7F; 73 | fe_frombytes(h, hash); 74 | elligator(u, h); 75 | 76 | ge_montx_to_p3(&p3, u, sign_bit); 77 | ge_scalarmult_cofactor(p, &p3); 78 | } 79 | 80 | 81 | -------------------------------------------------------------------------------- /curve/ed25519/additions/fe_isequal.c: -------------------------------------------------------------------------------- 1 | #include "fe.h" 2 | #include "crypto_verify_32.h" 3 | 4 | /* 5 | return 1 if f == g 6 | return 0 if f != g 7 | */ 8 | 9 | int fe_isequal(const fe f, const fe g) 10 | { 11 | fe h; 12 | fe_sub(h, f, g); 13 | return 1 ^ (1 & (fe_isnonzero(h) >> 8)); 14 | } 15 | -------------------------------------------------------------------------------- /curve/ed25519/additions/fe_isreduced.c: -------------------------------------------------------------------------------- 1 | #include "fe.h" 2 | #include "crypto_verify_32.h" 3 | 4 | int fe_isreduced(const unsigned char* s) 5 | { 6 | fe f; 7 | unsigned char strict[32]; 8 | 9 | fe_frombytes(f, s); 10 | fe_tobytes(strict, f); 11 | if (crypto_verify_32(strict, s) != 0) 12 | return 0; 13 | return 1; 14 | } 15 | -------------------------------------------------------------------------------- /curve/ed25519/additions/fe_mont_rhs.c: -------------------------------------------------------------------------------- 1 | #include "fe.h" 2 | 3 | void fe_mont_rhs(fe v2, fe u) { 4 | fe A, one; 5 | fe u2, Au, inner; 6 | 7 | fe_1(one); 8 | fe_0(A); 9 | A[0] = 486662; /* A = 486662 */ 10 | 11 | fe_sq(u2, u); /* u^2 */ 12 | fe_mul(Au, A, u); /* Au */ 13 | fe_add(inner, u2, Au); /* u^2 + Au */ 14 | fe_add(inner, inner, one); /* u^2 + Au + 1 */ 15 | fe_mul(v2, u, inner); /* u(u^2 + Au + 1) */ 16 | } 17 | 18 | -------------------------------------------------------------------------------- /curve/ed25519/additions/fe_montx_to_edy.c: -------------------------------------------------------------------------------- 1 | 2 | #include "fe.h" 3 | #include "crypto_additions.h" 4 | 5 | void fe_montx_to_edy(fe y, const fe u) 6 | { 7 | /* 8 | y = (u - 1) / (u + 1) 9 | 10 | NOTE: u=-1 is converted to y=0 since fe_invert is mod-exp 11 | */ 12 | fe one, um1, up1; 13 | 14 | fe_1(one); 15 | fe_sub(um1, u, one); 16 | fe_add(up1, u, one); 17 | fe_invert(up1, up1); 18 | fe_mul(y, um1, up1); 19 | } 20 | -------------------------------------------------------------------------------- /curve/ed25519/additions/fe_sqrt.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "fe.h" 3 | #include "crypto_additions.h" 4 | 5 | /* sqrt(-1) */ 6 | static unsigned char i_bytes[32] = { 7 | 0xb0, 0xa0, 0x0e, 0x4a, 0x27, 0x1b, 0xee, 0xc4, 8 | 0x78, 0xe4, 0x2f, 0xad, 0x06, 0x18, 0x43, 0x2f, 9 | 0xa7, 0xd7, 0xfb, 0x3d, 0x99, 0x00, 0x4d, 0x2b, 10 | 0x0b, 0xdf, 0xc1, 0x4f, 0x80, 0x24, 0x83, 0x2b 11 | }; 12 | 13 | /* Preconditions: a is square or zero */ 14 | 15 | void fe_sqrt(fe out, const fe a) 16 | { 17 | fe exp, b, b2, bi, i; 18 | #ifndef NDEBUG 19 | fe legendre, zero, one; 20 | #endif 21 | 22 | fe_frombytes(i, i_bytes); 23 | fe_pow22523(exp, a); /* b = a^(q-5)/8 */ 24 | 25 | /* PRECONDITION: legendre symbol == 1 (square) or 0 (a == zero) */ 26 | #ifndef NDEBUG 27 | fe_sq(legendre, exp); /* in^((q-5)/4) */ 28 | fe_sq(legendre, legendre); /* in^((q-5)/2) */ 29 | fe_mul(legendre, legendre, a); /* in^((q-3)/2) */ 30 | fe_mul(legendre, legendre, a); /* in^((q-1)/2) */ 31 | 32 | fe_0(zero); 33 | fe_1(one); 34 | assert(fe_isequal(legendre, zero) || fe_isequal(legendre, one)); 35 | #endif 36 | 37 | fe_mul(b, a, exp); /* b = a * a^(q-5)/8 */ 38 | fe_sq(b2, b); /* b^2 = a * a^(q-1)/4 */ 39 | 40 | /* note b^4 == a^2, so b^2 == a or -a 41 | * if b^2 != a, multiply it by sqrt(-1) */ 42 | fe_mul(bi, b, i); 43 | fe_cmov(b, bi, 1 ^ fe_isequal(b2, a)); 44 | fe_copy(out, b); 45 | 46 | /* PRECONDITION: out^2 == a */ 47 | #ifndef NDEBUG 48 | fe_sq(b2, out); 49 | assert(fe_isequal(a, b2)); 50 | #endif 51 | } 52 | -------------------------------------------------------------------------------- /curve/ed25519/additions/ge_isneutral.c: -------------------------------------------------------------------------------- 1 | #include "crypto_additions.h" 2 | #include "ge.h" 3 | 4 | /* 5 | return 1 if p is the neutral point 6 | return 0 otherwise 7 | */ 8 | 9 | int ge_isneutral(const ge_p3 *p) 10 | { 11 | fe zero; 12 | fe_0(zero); 13 | 14 | /* Check if p == neutral element == (0, 1) */ 15 | return (fe_isequal(p->X, zero) & fe_isequal(p->Y, p->Z)); 16 | } 17 | -------------------------------------------------------------------------------- /curve/ed25519/additions/ge_montx_to_p3.c: -------------------------------------------------------------------------------- 1 | #include "fe.h" 2 | #include "ge.h" 3 | #include "assert.h" 4 | #include "crypto_additions.h" 5 | #include "utility.h" 6 | 7 | /* sqrt(-(A+2)) */ 8 | static unsigned char A_bytes[32] = { 9 | 0x06, 0x7e, 0x45, 0xff, 0xaa, 0x04, 0x6e, 0xcc, 10 | 0x82, 0x1a, 0x7d, 0x4b, 0xd1, 0xd3, 0xa1, 0xc5, 11 | 0x7e, 0x4f, 0xfc, 0x03, 0xdc, 0x08, 0x7b, 0xd2, 12 | 0xbb, 0x06, 0xa0, 0x60, 0xf4, 0xed, 0x26, 0x0f 13 | }; 14 | 15 | void ge_montx_to_p3(ge_p3* p, const fe u, const unsigned char ed_sign_bit) 16 | { 17 | fe x, y, A, v, v2, iv, nx; 18 | 19 | fe_frombytes(A, A_bytes); 20 | 21 | /* given u, recover edwards y */ 22 | /* given u, recover v */ 23 | /* given u and v, recover edwards x */ 24 | 25 | fe_montx_to_edy(y, u); /* y = (u - 1) / (u + 1) */ 26 | 27 | fe_mont_rhs(v2, u); /* v^2 = u(u^2 + Au + 1) */ 28 | fe_sqrt(v, v2); /* v = sqrt(v^2) */ 29 | 30 | fe_mul(x, u, A); /* x = u * sqrt(-(A+2)) */ 31 | fe_invert(iv, v); /* 1/v */ 32 | fe_mul(x, x, iv); /* x = (u/v) * sqrt(-(A+2)) */ 33 | 34 | fe_neg(nx, x); /* negate x to match sign bit */ 35 | fe_cmov(x, nx, fe_isnegative(x) ^ ed_sign_bit); 36 | 37 | fe_copy(p->X, x); 38 | fe_copy(p->Y, y); 39 | fe_1(p->Z); 40 | fe_mul(p->T, p->X, p->Y); 41 | 42 | /* POSTCONDITION: check that p->X and p->Y satisfy the Ed curve equation */ 43 | /* -x^2 + y^2 = 1 + dx^2y^2 */ 44 | #ifndef NDEBUG 45 | { 46 | fe one, d, x2, y2, x2y2, dx2y2; 47 | 48 | unsigned char dbytes[32] = { 49 | 0xa3, 0x78, 0x59, 0x13, 0xca, 0x4d, 0xeb, 0x75, 50 | 0xab, 0xd8, 0x41, 0x41, 0x4d, 0x0a, 0x70, 0x00, 51 | 0x98, 0xe8, 0x79, 0x77, 0x79, 0x40, 0xc7, 0x8c, 52 | 0x73, 0xfe, 0x6f, 0x2b, 0xee, 0x6c, 0x03, 0x52 53 | }; 54 | 55 | fe_frombytes(d, dbytes); 56 | fe_1(one); 57 | fe_sq(x2, p->X); /* x^2 */ 58 | fe_sq(y2, p->Y); /* y^2 */ 59 | 60 | fe_mul(dx2y2, x2, y2); /* x^2y^2 */ 61 | fe_mul(dx2y2, dx2y2, d); /* dx^2y^2 */ 62 | fe_add(dx2y2, dx2y2, one); /* dx^2y^2 + 1 */ 63 | 64 | fe_neg(x2y2, x2); /* -x^2 */ 65 | fe_add(x2y2, x2y2, y2); /* -x^2 + y^2 */ 66 | 67 | assert(fe_isequal(x2y2, dx2y2)); 68 | } 69 | #endif 70 | } 71 | -------------------------------------------------------------------------------- /curve/ed25519/additions/ge_neg.c: -------------------------------------------------------------------------------- 1 | #include "crypto_additions.h" 2 | #include "ge.h" 3 | 4 | /* 5 | return r = -p 6 | */ 7 | 8 | 9 | void ge_neg(ge_p3* r, const ge_p3 *p) 10 | { 11 | fe_neg(r->X, p->X); 12 | fe_copy(r->Y, p->Y); 13 | fe_copy(r->Z, p->Z); 14 | fe_neg(r->T, p->T); 15 | } 16 | -------------------------------------------------------------------------------- /curve/ed25519/additions/ge_p3_to_montx.c: -------------------------------------------------------------------------------- 1 | #include "fe.h" 2 | #include "crypto_additions.h" 3 | 4 | void ge_p3_to_montx(fe u, const ge_p3 *ed) 5 | { 6 | /* 7 | u = (y + 1) / (1 - y) 8 | or 9 | u = (y + z) / (z - y) 10 | 11 | NOTE: y=1 is converted to u=0 since fe_invert is mod-exp 12 | */ 13 | 14 | fe y_plus_one, one_minus_y, inv_one_minus_y; 15 | 16 | fe_add(y_plus_one, ed->Y, ed->Z); 17 | fe_sub(one_minus_y, ed->Z, ed->Y); 18 | fe_invert(inv_one_minus_y, one_minus_y); 19 | fe_mul(u, y_plus_one, inv_one_minus_y); 20 | } 21 | 22 | -------------------------------------------------------------------------------- /curve/ed25519/additions/ge_scalarmult.c: -------------------------------------------------------------------------------- 1 | #include "crypto_uint32.h" 2 | #include "ge.h" 3 | #include "crypto_additions.h" 4 | 5 | static unsigned char equal(signed char b,signed char c) 6 | { 7 | unsigned char ub = b; 8 | unsigned char uc = c; 9 | unsigned char x = ub ^ uc; /* 0: yes; 1..255: no */ 10 | crypto_uint32 y = x; /* 0: yes; 1..255: no */ 11 | y -= 1; /* 4294967295: yes; 0..254: no */ 12 | y >>= 31; /* 1: yes; 0: no */ 13 | return y; 14 | } 15 | 16 | static unsigned char negative(signed char b) 17 | { 18 | unsigned long long x = b; /* 18446744073709551361..18446744073709551615: yes; 0..255: no */ 19 | x >>= 63; /* 1: yes; 0: no */ 20 | return x; 21 | } 22 | 23 | static void cmov(ge_cached *t,const ge_cached *u,unsigned char b) 24 | { 25 | fe_cmov(t->YplusX,u->YplusX,b); 26 | fe_cmov(t->YminusX,u->YminusX,b); 27 | fe_cmov(t->Z,u->Z,b); 28 | fe_cmov(t->T2d,u->T2d,b); 29 | } 30 | 31 | static void select(ge_cached *t,const ge_cached *pre, signed char b) 32 | { 33 | ge_cached minust; 34 | unsigned char bnegative = negative(b); 35 | unsigned char babs = b - (((-bnegative) & b) << 1); 36 | 37 | fe_1(t->YplusX); 38 | fe_1(t->YminusX); 39 | fe_1(t->Z); 40 | fe_0(t->T2d); 41 | 42 | cmov(t,pre+0,equal(babs,1)); 43 | cmov(t,pre+1,equal(babs,2)); 44 | cmov(t,pre+2,equal(babs,3)); 45 | cmov(t,pre+3,equal(babs,4)); 46 | cmov(t,pre+4,equal(babs,5)); 47 | cmov(t,pre+5,equal(babs,6)); 48 | cmov(t,pre+6,equal(babs,7)); 49 | cmov(t,pre+7,equal(babs,8)); 50 | fe_copy(minust.YplusX,t->YminusX); 51 | fe_copy(minust.YminusX,t->YplusX); 52 | fe_copy(minust.Z,t->Z); 53 | fe_neg(minust.T2d,t->T2d); 54 | cmov(t,&minust,bnegative); 55 | } 56 | 57 | /* 58 | h = a * B 59 | where a = a[0]+256*a[1]+...+256^31 a[31] 60 | B is the Ed25519 base point (x,4/5) with x positive. 61 | 62 | Preconditions: 63 | a[31] <= 127 64 | */ 65 | 66 | void ge_scalarmult(ge_p3 *h, const unsigned char *a, const ge_p3 *A) 67 | { 68 | signed char e[64]; 69 | signed char carry; 70 | ge_p1p1 r; 71 | ge_p2 s; 72 | ge_p3 t0, t1, t2; 73 | ge_cached t, pre[8]; 74 | int i; 75 | 76 | for (i = 0;i < 32;++i) { 77 | e[2 * i + 0] = (a[i] >> 0) & 15; 78 | e[2 * i + 1] = (a[i] >> 4) & 15; 79 | } 80 | /* each e[i] is between 0 and 15 */ 81 | /* e[63] is between 0 and 7 */ 82 | 83 | carry = 0; 84 | for (i = 0;i < 63;++i) { 85 | e[i] += carry; 86 | carry = e[i] + 8; 87 | carry >>= 4; 88 | e[i] -= carry << 4; 89 | } 90 | e[63] += carry; 91 | /* each e[i] is between -8 and 8 */ 92 | 93 | // Precomputation: 94 | ge_p3_to_cached(pre+0, A); // A 95 | 96 | ge_p3_dbl(&r, A); 97 | ge_p1p1_to_p3(&t0, &r); 98 | ge_p3_to_cached(pre+1, &t0); // 2A 99 | 100 | ge_add(&r, A, pre+1); 101 | ge_p1p1_to_p3(&t1, &r); 102 | ge_p3_to_cached(pre+2, &t1); // 3A 103 | 104 | ge_p3_dbl(&r, &t0); 105 | ge_p1p1_to_p3(&t0, &r); 106 | ge_p3_to_cached(pre+3, &t0); // 4A 107 | 108 | ge_add(&r, A, pre+3); 109 | ge_p1p1_to_p3(&t2, &r); 110 | ge_p3_to_cached(pre+4, &t2); // 5A 111 | 112 | ge_p3_dbl(&r, &t1); 113 | ge_p1p1_to_p3(&t1, &r); 114 | ge_p3_to_cached(pre+5, &t1); // 6A 115 | 116 | ge_add(&r, A, pre+5); 117 | ge_p1p1_to_p3(&t1, &r); 118 | ge_p3_to_cached(pre+6, &t1); // 7A 119 | 120 | ge_p3_dbl(&r, &t0); 121 | ge_p1p1_to_p3(&t0, &r); 122 | ge_p3_to_cached(pre+7, &t0); // 8A 123 | 124 | ge_p3_0(h); 125 | 126 | for (i = 63;i > 0; i--) { 127 | select(&t,pre,e[i]); 128 | ge_add(&r, h, &t); 129 | ge_p1p1_to_p2(&s,&r); 130 | 131 | ge_p2_dbl(&r,&s); ge_p1p1_to_p2(&s,&r); 132 | ge_p2_dbl(&r,&s); ge_p1p1_to_p2(&s,&r); 133 | ge_p2_dbl(&r,&s); ge_p1p1_to_p2(&s,&r); 134 | ge_p2_dbl(&r,&s); ge_p1p1_to_p3(h,&r); 135 | 136 | } 137 | select(&t,pre,e[0]); 138 | ge_add(&r, h, &t); 139 | ge_p1p1_to_p3(h,&r); 140 | } 141 | -------------------------------------------------------------------------------- /curve/ed25519/additions/ge_scalarmult_cofactor.c: -------------------------------------------------------------------------------- 1 | #include "crypto_additions.h" 2 | #include "ge.h" 3 | 4 | /* 5 | return 8 * p 6 | */ 7 | 8 | void ge_scalarmult_cofactor(ge_p3 *q, const ge_p3 *p) 9 | { 10 | ge_p1p1 p1p1; 11 | ge_p2 p2; 12 | 13 | ge_p3_dbl(&p1p1, p); 14 | ge_p1p1_to_p2(&p2, &p1p1); 15 | 16 | ge_p2_dbl(&p1p1, &p2); 17 | ge_p1p1_to_p2(&p2, &p1p1); 18 | 19 | ge_p2_dbl(&p1p1, &p2); 20 | ge_p1p1_to_p3(q, &p1p1); 21 | } 22 | -------------------------------------------------------------------------------- /curve/ed25519/additions/generalized/ge_p3_add.c: -------------------------------------------------------------------------------- 1 | #include "ge.h" 2 | 3 | /* 4 | r = p + q 5 | */ 6 | 7 | void ge_p3_add(ge_p3 *r, const ge_p3 *p, const ge_p3 *q) 8 | { 9 | ge_cached p_cached; 10 | ge_p1p1 r_p1p1; 11 | 12 | ge_p3_to_cached(&p_cached, p); 13 | ge_add(&r_p1p1, q, &p_cached); 14 | ge_p1p1_to_p3(r, &r_p1p1); 15 | } 16 | -------------------------------------------------------------------------------- /curve/ed25519/additions/generalized/gen_constants.h: -------------------------------------------------------------------------------- 1 | #ifndef _GEN_CONSTANTS_H__ 2 | #define _GEN_CONSTANTS_H__ 3 | 4 | #define LABELSETMAXLEN 512 5 | #define LABELMAXLEN 128 6 | #define BUFLEN 1024 7 | #define BLOCKLEN 128 /* SHA512 */ 8 | #define HASHLEN 64 /* SHA512 */ 9 | #define POINTLEN 32 10 | #define SCALARLEN 32 11 | #define RANDLEN 32 12 | #define SIGNATURELEN 64 13 | #define VRFSIGNATURELEN 96 14 | #define VRFOUTPUTLEN 32 15 | #define MSTART 2048 16 | #define MSGMAXLEN 1048576 17 | 18 | #endif 19 | 20 | -------------------------------------------------------------------------------- /curve/ed25519/additions/generalized/gen_crypto_additions.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef __GEN_CRYPTO_ADDITIONS__ 3 | #define __GEN_CRYPTO_ADDITIONS__ 4 | 5 | #include "crypto_uint32.h" 6 | #include "fe.h" 7 | #include "ge.h" 8 | 9 | int sc_isreduced(const unsigned char* s); 10 | 11 | int point_isreduced(const unsigned char* p); 12 | 13 | void ge_p3_add(ge_p3 *r, const ge_p3 *p, const ge_p3 *q); 14 | 15 | #endif 16 | 17 | -------------------------------------------------------------------------------- /curve/ed25519/additions/generalized/gen_eddsa.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "gen_eddsa.h" 3 | #include "gen_labelset.h" 4 | #include "gen_constants.h" 5 | #include "gen_crypto_additions.h" 6 | #include "crypto_hash_sha512.h" 7 | #include "crypto_verify_32.h" 8 | #include "zeroize.h" 9 | #include "ge.h" 10 | #include "sc.h" 11 | #include "crypto_additions.h" 12 | #include "utility.h" 13 | 14 | /* B: base point 15 | * R: commitment (point), 16 | r: private nonce (scalar) 17 | K: encoded public key 18 | k: private key (scalar) 19 | Z: 32-bytes random 20 | M: buffer containing message, message starts at M_start, continues for M_len 21 | 22 | r = hash(B || labelset || Z || pad1 || k || pad2 || labelset || K || extra || M) (mod q) 23 | */ 24 | int generalized_commit(unsigned char* R_bytes, unsigned char* r_scalar, 25 | const unsigned char* labelset, const unsigned long labelset_len, 26 | const unsigned char* extra, const unsigned long extra_len, 27 | const unsigned char* K_bytes, const unsigned char* k_scalar, 28 | const unsigned char* Z, 29 | unsigned char* M_buf, const unsigned long M_start, const unsigned long M_len) 30 | { 31 | ge_p3 R_point; 32 | unsigned char hash[HASHLEN]; 33 | unsigned char* bufstart = NULL; 34 | unsigned char* bufptr = NULL; 35 | unsigned char* bufend = NULL; 36 | unsigned long prefix_len = 0; 37 | 38 | if (labelset_validate(labelset, labelset_len) != 0) 39 | goto err; 40 | if (R_bytes == NULL || r_scalar == NULL || 41 | K_bytes == NULL || k_scalar == NULL || 42 | Z == NULL || M_buf == NULL) 43 | goto err; 44 | if (extra == NULL && extra_len != 0) 45 | goto err; 46 | if (extra != NULL && extra_len == 0) 47 | goto err; 48 | if (extra != NULL && labelset_is_empty(labelset, labelset_len)) 49 | goto err; 50 | if (HASHLEN != 64) 51 | goto err; 52 | 53 | prefix_len = 0; 54 | prefix_len += POINTLEN + labelset_len + RANDLEN; 55 | prefix_len += ((BLOCKLEN - (prefix_len % BLOCKLEN)) % BLOCKLEN); 56 | prefix_len += SCALARLEN; 57 | prefix_len += ((BLOCKLEN - (prefix_len % BLOCKLEN)) % BLOCKLEN); 58 | prefix_len += labelset_len + POINTLEN + extra_len; 59 | if (prefix_len > M_start) 60 | goto err; 61 | 62 | bufstart = M_buf + M_start - prefix_len; 63 | bufptr = bufstart; 64 | bufend = M_buf + M_start; 65 | bufptr = buffer_add(bufptr, bufend, B_bytes, POINTLEN); 66 | bufptr = buffer_add(bufptr, bufend, labelset, labelset_len); 67 | bufptr = buffer_add(bufptr, bufend, Z, RANDLEN); 68 | bufptr = buffer_pad(bufstart, bufptr, bufend); 69 | bufptr = buffer_add(bufptr, bufend, k_scalar, SCALARLEN); 70 | bufptr = buffer_pad(bufstart, bufptr, bufend); 71 | bufptr = buffer_add(bufptr, bufend, labelset, labelset_len); 72 | bufptr = buffer_add(bufptr, bufend, K_bytes, POINTLEN); 73 | bufptr = buffer_add(bufptr, bufend, extra, extra_len); 74 | if (bufptr != bufend || bufptr != M_buf + M_start || bufptr - bufstart != prefix_len) 75 | goto err; 76 | 77 | crypto_hash_sha512(hash, M_buf + M_start - prefix_len, prefix_len + M_len); 78 | sc_reduce(hash); 79 | ge_scalarmult_base(&R_point, hash); 80 | ge_p3_tobytes(R_bytes, &R_point); 81 | memcpy(r_scalar, hash, SCALARLEN); 82 | 83 | zeroize(hash, HASHLEN); 84 | zeroize(bufstart, prefix_len); 85 | return 0; 86 | 87 | err: 88 | zeroize(hash, HASHLEN); 89 | zeroize(M_buf, M_start); 90 | return -1; 91 | } 92 | 93 | /* if is_labelset_empty(labelset): 94 | return hash(R || K || M) (mod q) 95 | else: 96 | return hash(B || labelset || R || labelset || K || extra || M) (mod q) 97 | */ 98 | int generalized_challenge(unsigned char* h_scalar, 99 | const unsigned char* labelset, const unsigned long labelset_len, 100 | const unsigned char* extra, const unsigned long extra_len, 101 | const unsigned char* R_bytes, 102 | const unsigned char* K_bytes, 103 | unsigned char* M_buf, const unsigned long M_start, const unsigned long M_len) 104 | { 105 | unsigned char hash[HASHLEN]; 106 | unsigned char* bufstart = NULL; 107 | unsigned char* bufptr = NULL; 108 | unsigned char* bufend = NULL; 109 | unsigned long prefix_len = 0; 110 | 111 | if (h_scalar == NULL) 112 | goto err; 113 | memset(h_scalar, 0, SCALARLEN); 114 | 115 | if (labelset_validate(labelset, labelset_len) != 0) 116 | goto err; 117 | if (R_bytes == NULL || K_bytes == NULL || M_buf == NULL) 118 | goto err; 119 | if (extra == NULL && extra_len != 0) 120 | goto err; 121 | if (extra != NULL && extra_len == 0) 122 | goto err; 123 | if (extra != NULL && labelset_is_empty(labelset, labelset_len)) 124 | goto err; 125 | if (HASHLEN != 64) 126 | goto err; 127 | 128 | if (labelset_is_empty(labelset, labelset_len)) { 129 | if (2*POINTLEN > M_start) 130 | goto err; 131 | if (extra != NULL || extra_len != 0) 132 | goto err; 133 | memcpy(M_buf + M_start - (2*POINTLEN), R_bytes, POINTLEN); 134 | memcpy(M_buf + M_start - (1*POINTLEN), K_bytes, POINTLEN); 135 | prefix_len = 2*POINTLEN; 136 | } else { 137 | prefix_len = 3*POINTLEN + 2*labelset_len + extra_len; 138 | if (prefix_len > M_start) 139 | goto err; 140 | 141 | bufstart = M_buf + M_start - prefix_len; 142 | bufptr = bufstart; 143 | bufend = M_buf + M_start; 144 | bufptr = buffer_add(bufptr, bufend, B_bytes, POINTLEN); 145 | bufptr = buffer_add(bufptr, bufend, labelset, labelset_len); 146 | bufptr = buffer_add(bufptr, bufend, R_bytes, POINTLEN); 147 | bufptr = buffer_add(bufptr, bufend, labelset, labelset_len); 148 | bufptr = buffer_add(bufptr, bufend, K_bytes, POINTLEN); 149 | bufptr = buffer_add(bufptr, bufend, extra, extra_len); 150 | 151 | if (bufptr == NULL) 152 | goto err; 153 | if (bufptr != bufend || bufptr != M_buf + M_start || bufptr - bufstart != prefix_len) 154 | goto err; 155 | } 156 | 157 | crypto_hash_sha512(hash, M_buf + M_start - prefix_len, prefix_len + M_len); 158 | sc_reduce(hash); 159 | memcpy(h_scalar, hash, SCALARLEN); 160 | return 0; 161 | 162 | err: 163 | return -1; 164 | } 165 | 166 | /* return r + kh (mod q) */ 167 | int generalized_prove(unsigned char* out_scalar, 168 | const unsigned char* r_scalar, const unsigned char* k_scalar, const unsigned char* h_scalar) 169 | { 170 | sc_muladd(out_scalar, h_scalar, k_scalar, r_scalar); 171 | zeroize_stack(); 172 | return 0; 173 | } 174 | 175 | /* R = s*B - h*K */ 176 | int generalized_solve_commitment(unsigned char* R_bytes_out, ge_p3* K_point_out, 177 | const ge_p3* B_point, const unsigned char* s_scalar, 178 | const unsigned char* K_bytes, const unsigned char* h_scalar) 179 | { 180 | 181 | ge_p3 Kneg_point; 182 | ge_p2 R_calc_point_p2; 183 | 184 | ge_p3 sB; 185 | ge_p3 hK; 186 | ge_p3 R_calc_point_p3; 187 | 188 | if (ge_frombytes_negate_vartime(&Kneg_point, K_bytes) != 0) 189 | return -1; 190 | 191 | if (B_point == NULL) { 192 | ge_double_scalarmult_vartime(&R_calc_point_p2, h_scalar, &Kneg_point, s_scalar); 193 | ge_tobytes(R_bytes_out, &R_calc_point_p2); 194 | } 195 | else { 196 | // s * Bv 197 | ge_scalarmult(&sB, s_scalar, B_point); 198 | 199 | // h * -K 200 | ge_scalarmult(&hK, h_scalar, &Kneg_point); 201 | 202 | // R = sB - hK 203 | ge_p3_add(&R_calc_point_p3, &sB, &hK); 204 | ge_p3_tobytes(R_bytes_out, &R_calc_point_p3); 205 | } 206 | 207 | if (K_point_out) { 208 | ge_neg(K_point_out, &Kneg_point); 209 | } 210 | 211 | return 0; 212 | } 213 | 214 | 215 | int generalized_eddsa_25519_sign( 216 | unsigned char* signature_out, 217 | const unsigned char* eddsa_25519_pubkey_bytes, 218 | const unsigned char* eddsa_25519_privkey_scalar, 219 | const unsigned char* msg, 220 | const unsigned long msg_len, 221 | const unsigned char* random, 222 | const unsigned char* customization_label, 223 | const unsigned long customization_label_len) 224 | { 225 | unsigned char labelset[LABELSETMAXLEN]; 226 | unsigned long labelset_len = 0; 227 | unsigned char R_bytes[POINTLEN]; 228 | unsigned char r_scalar[SCALARLEN]; 229 | unsigned char h_scalar[SCALARLEN]; 230 | unsigned char s_scalar[SCALARLEN]; 231 | unsigned char* M_buf = NULL; 232 | 233 | if (signature_out == NULL) 234 | goto err; 235 | memset(signature_out, 0, SIGNATURELEN); 236 | 237 | if (eddsa_25519_pubkey_bytes == NULL) 238 | goto err; 239 | if (eddsa_25519_privkey_scalar == NULL) 240 | goto err; 241 | if (msg == NULL) 242 | goto err; 243 | if (customization_label == NULL && customization_label_len != 0) 244 | goto err; 245 | if (customization_label_len > LABELMAXLEN) 246 | goto err; 247 | if (msg_len > MSGMAXLEN) 248 | goto err; 249 | 250 | if ((M_buf = malloc(msg_len + MSTART)) == 0) 251 | goto err; 252 | memcpy(M_buf + MSTART, msg, msg_len); 253 | 254 | if (labelset_new(labelset, &labelset_len, LABELSETMAXLEN, NULL, 0, 255 | customization_label, customization_label_len) != 0) 256 | goto err; 257 | 258 | if (generalized_commit(R_bytes, r_scalar, labelset, labelset_len, NULL, 0, 259 | eddsa_25519_pubkey_bytes, eddsa_25519_privkey_scalar, 260 | random, M_buf, MSTART, msg_len) != 0) 261 | goto err; 262 | 263 | if (generalized_challenge(h_scalar, labelset, labelset_len, NULL, 0, 264 | R_bytes, eddsa_25519_pubkey_bytes, M_buf, MSTART, msg_len) != 0) 265 | goto err; 266 | 267 | if (generalized_prove(s_scalar, r_scalar, eddsa_25519_privkey_scalar, h_scalar) != 0) 268 | goto err; 269 | 270 | memcpy(signature_out, R_bytes, POINTLEN); 271 | memcpy(signature_out + POINTLEN, s_scalar, SCALARLEN); 272 | 273 | zeroize(r_scalar, SCALARLEN); 274 | zeroize_stack(); 275 | free(M_buf); 276 | return 0; 277 | 278 | err: 279 | zeroize(r_scalar, SCALARLEN); 280 | zeroize_stack(); 281 | free(M_buf); 282 | return -1; 283 | } 284 | 285 | int generalized_eddsa_25519_verify( 286 | const unsigned char* signature, 287 | const unsigned char* eddsa_25519_pubkey_bytes, 288 | const unsigned char* msg, 289 | const unsigned long msg_len, 290 | const unsigned char* customization_label, 291 | const unsigned long customization_label_len) 292 | { 293 | unsigned char labelset[LABELSETMAXLEN]; 294 | unsigned long labelset_len = 0; 295 | const unsigned char* R_bytes = NULL; 296 | const unsigned char* s_scalar = NULL; 297 | unsigned char h_scalar[SCALARLEN]; 298 | unsigned char* M_buf = NULL; 299 | unsigned char R_calc_bytes[POINTLEN]; 300 | 301 | if (signature == NULL) 302 | goto err; 303 | if (eddsa_25519_pubkey_bytes == NULL) 304 | goto err; 305 | if (msg == NULL) 306 | goto err; 307 | if (customization_label == NULL && customization_label_len != 0) 308 | goto err; 309 | if (customization_label_len > LABELMAXLEN) 310 | goto err; 311 | if (msg_len > MSGMAXLEN) 312 | goto err; 313 | 314 | if ((M_buf = malloc(msg_len + MSTART)) == 0) 315 | goto err; 316 | memcpy(M_buf + MSTART, msg, msg_len); 317 | 318 | if (labelset_new(labelset, &labelset_len, LABELSETMAXLEN, NULL, 0, 319 | customization_label, customization_label_len) != 0) 320 | goto err; 321 | 322 | R_bytes = signature; 323 | s_scalar = signature + POINTLEN; 324 | 325 | if (!point_isreduced(eddsa_25519_pubkey_bytes)) 326 | goto err; 327 | if (!point_isreduced(R_bytes)) 328 | goto err; 329 | if (!sc_isreduced(s_scalar)) 330 | goto err; 331 | 332 | if (generalized_challenge(h_scalar, labelset, labelset_len, 333 | NULL, 0, R_bytes, eddsa_25519_pubkey_bytes, M_buf, MSTART, msg_len) != 0) 334 | goto err; 335 | 336 | if (generalized_solve_commitment(R_calc_bytes, NULL, NULL, 337 | s_scalar, eddsa_25519_pubkey_bytes, h_scalar) != 0) 338 | goto err; 339 | 340 | if (crypto_verify_32(R_bytes, R_calc_bytes) != 0) 341 | goto err; 342 | 343 | free(M_buf); 344 | return 0; 345 | 346 | err: 347 | free(M_buf); 348 | return -1; 349 | } 350 | -------------------------------------------------------------------------------- /curve/ed25519/additions/generalized/gen_eddsa.h: -------------------------------------------------------------------------------- 1 | #ifndef __GEN_EDDSA_H__ 2 | #define __GEN_EDDSA_H__ 3 | 4 | #include "ge.h" 5 | 6 | /* B: base point 7 | R: commitment (point), 8 | r: private nonce (scalar) 9 | K: encoded public key 10 | k: private key (scalar) 11 | Z: 32-bytes random 12 | M: buffer containing message, message starts at M_start, continues for M_len 13 | 14 | r = hash(B || labelset || Z || pad1 || k || pad2 || labelset || K || extra || M) (mod q) 15 | */ 16 | int generalized_commit(unsigned char* R_bytes, unsigned char* r_scalar, 17 | const unsigned char* labelset, const unsigned long labelset_len, 18 | const unsigned char* extra, const unsigned long extra_len, 19 | const unsigned char* K_bytes, const unsigned char* k_scalar, 20 | const unsigned char* Z, 21 | unsigned char* M_buf, const unsigned long M_start, const unsigned long M_len); 22 | 23 | /* if is_labelset_empty(labelset): 24 | return hash(R || K || M) (mod q) 25 | else: 26 | return hash(B || labelset || R || labelset || K || extra || M) (mod q) 27 | */ 28 | int generalized_challenge(unsigned char* h_scalar, 29 | const unsigned char* labelset, const unsigned long labelset_len, 30 | const unsigned char* extra, const unsigned long extra_len, 31 | const unsigned char* R_bytes, 32 | const unsigned char* K_bytes, 33 | unsigned char* M_buf, const unsigned long M_start, const unsigned long M_len); 34 | 35 | /* return r + kh (mod q) */ 36 | int generalized_prove(unsigned char* out_scalar, 37 | const unsigned char* r_scalar, 38 | const unsigned char* k_scalar, 39 | const unsigned char* h_scalar); 40 | 41 | /* R = B^s / K^h */ 42 | int generalized_solve_commitment(unsigned char* R_bytes_out, ge_p3* K_point_out, 43 | const ge_p3* B_point, const unsigned char* s_scalar, 44 | const unsigned char* K_bytes, const unsigned char* h_scalar); 45 | 46 | 47 | int generalized_eddsa_25519_sign( 48 | unsigned char* signature_out, 49 | const unsigned char* eddsa_25519_pubkey_bytes, 50 | const unsigned char* eddsa_25519_privkey_scalar, 51 | const unsigned char* msg, 52 | const unsigned long msg_len, 53 | const unsigned char* random, 54 | const unsigned char* customization_label, 55 | const unsigned long customization_label_len); 56 | 57 | int generalized_eddsa_25519_verify( 58 | const unsigned char* signature, 59 | const unsigned char* eddsa_25519_pubkey, 60 | const unsigned char* msg, 61 | const unsigned long msg_len, 62 | const unsigned char* customization_label, 63 | const unsigned long customization_label_len); 64 | 65 | #endif 66 | -------------------------------------------------------------------------------- /curve/ed25519/additions/generalized/gen_labelset.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "gen_labelset.h" 4 | #include "gen_constants.h" 5 | 6 | const unsigned char B_bytes[] = { 7 | 0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 8 | 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 9 | 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 10 | 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 11 | }; 12 | 13 | unsigned char* buffer_add(unsigned char* bufptr, const unsigned char* bufend, 14 | const unsigned char* in, const unsigned long in_len) 15 | { 16 | unsigned long count = 0; 17 | 18 | if (bufptr == NULL || bufend == NULL || bufptr > bufend) 19 | return NULL; 20 | if (in == NULL && in_len != 0) 21 | return NULL; 22 | if (bufend - bufptr < in_len) 23 | return NULL; 24 | 25 | for (count=0; count < in_len; count++) { 26 | if (bufptr >= bufend) 27 | return NULL; 28 | *bufptr++ = *in++; 29 | } 30 | return bufptr; 31 | } 32 | 33 | unsigned char* buffer_pad(const unsigned char* buf, unsigned char* bufptr, const unsigned char* bufend) 34 | { 35 | unsigned long count = 0; 36 | unsigned long pad_len = 0; 37 | 38 | if (buf == NULL || bufptr == NULL || bufend == NULL || bufptr >= bufend || bufptr < buf) 39 | return NULL; 40 | 41 | pad_len = (BLOCKLEN - ((bufptr-buf) % BLOCKLEN)) % BLOCKLEN; 42 | if (bufend - bufptr < pad_len) 43 | return NULL; 44 | 45 | for (count=0; count < pad_len; count++) { 46 | if (bufptr >= bufend) 47 | return NULL; 48 | *bufptr++ = 0; 49 | } 50 | return bufptr; 51 | } 52 | 53 | int labelset_new(unsigned char* labelset, unsigned long* labelset_len, const unsigned long labelset_maxlen, 54 | const unsigned char* protocol_name, const unsigned char protocol_name_len, 55 | const unsigned char* customization_label, const unsigned char customization_label_len) 56 | { 57 | unsigned char* bufptr; 58 | 59 | *labelset_len = 0; 60 | if (labelset == NULL) 61 | return -1; 62 | if (labelset_len == NULL) 63 | return -1; 64 | if (labelset_maxlen > LABELSETMAXLEN) 65 | return -1; 66 | if (labelset_maxlen < 3 + protocol_name_len + customization_label_len) 67 | return -1; 68 | if (protocol_name == NULL && protocol_name_len != 0) 69 | return -1; 70 | if (customization_label == NULL && customization_label_len != 0) 71 | return -1; 72 | if (protocol_name_len > LABELMAXLEN) 73 | return -1; 74 | if (customization_label_len > LABELMAXLEN) 75 | return -1; 76 | 77 | bufptr = labelset; 78 | *bufptr++ = 2; 79 | *bufptr++ = protocol_name_len; 80 | bufptr = buffer_add(bufptr, labelset + labelset_maxlen, protocol_name, protocol_name_len); 81 | if (bufptr != NULL && bufptr < labelset + labelset_maxlen) 82 | *bufptr++ = customization_label_len; 83 | bufptr = buffer_add(bufptr, labelset + labelset_maxlen, 84 | customization_label, customization_label_len); 85 | 86 | if (bufptr != NULL && bufptr - labelset == 3 + protocol_name_len + customization_label_len) { 87 | *labelset_len = bufptr - labelset; 88 | return 0; 89 | } 90 | return -1; 91 | } 92 | 93 | 94 | int labelset_add(unsigned char* labelset, unsigned long* labelset_len, const unsigned long labelset_maxlen, 95 | const unsigned char* label, const unsigned char label_len) 96 | { 97 | unsigned char* bufptr; 98 | if (labelset_len == NULL) 99 | return -1; 100 | if (*labelset_len > LABELSETMAXLEN || labelset_maxlen > LABELSETMAXLEN) 101 | return -1; 102 | if (*labelset_len >= labelset_maxlen || *labelset_len + label_len + 1 > labelset_maxlen) 103 | return -1; 104 | if (*labelset_len < 3 || labelset_maxlen < 4) 105 | return -1; 106 | if (label_len > LABELMAXLEN) 107 | return -1; 108 | 109 | labelset[0]++; 110 | labelset[*labelset_len] = label_len; 111 | bufptr = labelset + *labelset_len + 1; 112 | bufptr = buffer_add(bufptr, labelset + labelset_maxlen, label, label_len); 113 | if (bufptr == NULL) 114 | return -1; 115 | if (bufptr - labelset >= labelset_maxlen) 116 | return -1; 117 | if (bufptr - labelset != *labelset_len + 1 + label_len) 118 | return -1; 119 | 120 | *labelset_len += (1 + label_len); 121 | return 0; 122 | } 123 | 124 | int labelset_validate(const unsigned char* labelset, const unsigned long labelset_len) 125 | { 126 | unsigned char num_labels = 0; 127 | unsigned char count = 0; 128 | unsigned long offset = 0; 129 | unsigned char label_len = 0; 130 | 131 | if (labelset == NULL) 132 | return -1; 133 | if (labelset_len < 3 || labelset_len > LABELSETMAXLEN) 134 | return -1; 135 | 136 | num_labels = labelset[0]; 137 | offset = 1; 138 | for (count = 0; count < num_labels; count++) { 139 | label_len = labelset[offset]; 140 | if (label_len > LABELMAXLEN) 141 | return -1; 142 | offset += 1 + label_len; 143 | if (offset > labelset_len) 144 | return -1; 145 | } 146 | if (offset != labelset_len) 147 | return -1; 148 | return 0; 149 | } 150 | 151 | int labelset_is_empty(const unsigned char* labelset, const unsigned long labelset_len) 152 | { 153 | if (labelset_len != 3) 154 | return 0; 155 | return 1; 156 | } 157 | 158 | -------------------------------------------------------------------------------- /curve/ed25519/additions/generalized/gen_labelset.h: -------------------------------------------------------------------------------- 1 | #ifndef __GEN_LABELSET_H__ 2 | #define __GEN_LABELSET_H__ 3 | 4 | extern const unsigned char B_bytes[]; 5 | 6 | unsigned char* buffer_add(unsigned char* bufptr, const unsigned char* bufend, 7 | const unsigned char* in, const unsigned long in_len); 8 | 9 | unsigned char* buffer_pad(const unsigned char* buf, unsigned char* bufptr, const unsigned char* bufend); 10 | 11 | 12 | int labelset_new(unsigned char* labelset, unsigned long* labelset_len, const unsigned long labelset_maxlen, 13 | const unsigned char* protocol_name, const unsigned char protocol_name_len, 14 | const unsigned char* customization_label, const unsigned char customization_label_len); 15 | 16 | int labelset_add(unsigned char* labelset, unsigned long* labelset_len, const unsigned long labelset_maxlen, 17 | const unsigned char* label, const unsigned char label_len); 18 | 19 | int labelset_validate(const unsigned char* labelset, const unsigned long labelset_len); 20 | 21 | int labelset_is_empty(const unsigned char* labelset, const unsigned long labelset_len); 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /curve/ed25519/additions/generalized/gen_veddsa.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "gen_eddsa.h" 3 | #include "gen_veddsa.h" 4 | #include "gen_constants.h" 5 | #include "gen_labelset.h" 6 | #include "gen_crypto_additions.h" 7 | #include "crypto_hash_sha512.h" 8 | #include "crypto_verify_32.h" 9 | #include "crypto_additions.h" 10 | #include "zeroize.h" 11 | #include "ge.h" 12 | #include "sc.h" 13 | #include "utility.h" 14 | 15 | static int generalized_calculate_Bv(ge_p3* Bv_point, 16 | const unsigned char* labelset, const unsigned long labelset_len, 17 | const unsigned char* K_bytes, 18 | unsigned char* M_buf, const unsigned long M_start, const unsigned long M_len) 19 | { 20 | unsigned char* bufptr; 21 | unsigned long prefix_len = 0; 22 | 23 | if (labelset_validate(labelset, labelset_len) != 0) 24 | return -1; 25 | if (Bv_point == NULL || K_bytes == NULL || M_buf == NULL) 26 | return -1; 27 | 28 | prefix_len = 2*POINTLEN + labelset_len; 29 | if (prefix_len > M_start) 30 | return -1; 31 | 32 | bufptr = M_buf + M_start - prefix_len; 33 | bufptr = buffer_add(bufptr, M_buf + M_start, B_bytes, POINTLEN); 34 | bufptr = buffer_add(bufptr, M_buf + M_start, labelset, labelset_len); 35 | bufptr = buffer_add(bufptr, M_buf + M_start, K_bytes, POINTLEN); 36 | if (bufptr == NULL || bufptr != M_buf + M_start) 37 | return -1; 38 | 39 | hash_to_point(Bv_point, M_buf + M_start - prefix_len, prefix_len + M_len); 40 | if (ge_isneutral(Bv_point)) 41 | return -1; 42 | return 0; 43 | } 44 | 45 | static int generalized_calculate_vrf_output(unsigned char* vrf_output, 46 | const unsigned char* labelset, const unsigned long labelset_len, 47 | const ge_p3* cKv_point) 48 | { 49 | unsigned char buf[BUFLEN]; 50 | unsigned char* bufptr = buf; 51 | unsigned char* bufend = buf + BUFLEN; 52 | unsigned char cKv_bytes[POINTLEN]; 53 | unsigned char hash[HASHLEN]; 54 | 55 | if (vrf_output == NULL) 56 | return -1; 57 | memset(vrf_output, 0, VRFOUTPUTLEN); 58 | 59 | if (labelset_len + 2*POINTLEN > BUFLEN) 60 | return -1; 61 | if (labelset_validate(labelset, labelset_len) != 0) 62 | return -1; 63 | if (cKv_point == NULL) 64 | return -1; 65 | if (VRFOUTPUTLEN > HASHLEN) 66 | return -1; 67 | 68 | ge_p3_tobytes(cKv_bytes, cKv_point); 69 | 70 | bufptr = buffer_add(bufptr, bufend, B_bytes, POINTLEN); 71 | bufptr = buffer_add(bufptr, bufend, labelset, labelset_len); 72 | bufptr = buffer_add(bufptr, bufend, cKv_bytes, POINTLEN); 73 | if (bufptr == NULL) 74 | return -1; 75 | if (bufptr - buf > BUFLEN) 76 | return -1; 77 | crypto_hash_sha512(hash, buf, bufptr - buf); 78 | memcpy(vrf_output, hash, VRFOUTPUTLEN); 79 | return 0; 80 | } 81 | 82 | int generalized_veddsa_25519_sign( 83 | unsigned char* signature_out, 84 | const unsigned char* eddsa_25519_pubkey_bytes, 85 | const unsigned char* eddsa_25519_privkey_scalar, 86 | const unsigned char* msg, 87 | const unsigned long msg_len, 88 | const unsigned char* random, 89 | const unsigned char* customization_label, 90 | const unsigned long customization_label_len) 91 | { 92 | unsigned char labelset[LABELSETMAXLEN]; 93 | unsigned long labelset_len = 0; 94 | ge_p3 Bv_point; 95 | ge_p3 Kv_point; 96 | ge_p3 Rv_point; 97 | unsigned char Bv_bytes[POINTLEN]; 98 | unsigned char Kv_bytes[POINTLEN]; 99 | unsigned char Rv_bytes[POINTLEN]; 100 | unsigned char R_bytes[POINTLEN]; 101 | unsigned char r_scalar[SCALARLEN]; 102 | unsigned char h_scalar[SCALARLEN]; 103 | unsigned char s_scalar[SCALARLEN]; 104 | unsigned char extra[3*POINTLEN]; 105 | unsigned char* M_buf = NULL; 106 | char* protocol_name = "VEdDSA_25519_SHA512_Elligator2"; 107 | 108 | if (signature_out == NULL) 109 | goto err; 110 | memset(signature_out, 0, VRFSIGNATURELEN); 111 | 112 | if (eddsa_25519_pubkey_bytes == NULL) 113 | goto err; 114 | if (eddsa_25519_privkey_scalar == NULL) 115 | goto err; 116 | if (msg == NULL) 117 | goto err; 118 | if (customization_label == NULL && customization_label_len != 0) 119 | goto err; 120 | if (customization_label_len > LABELMAXLEN) 121 | goto err; 122 | if (msg_len > MSGMAXLEN) 123 | goto err; 124 | 125 | if ((M_buf = malloc(msg_len + MSTART)) == 0) { 126 | goto err; 127 | } 128 | memcpy(M_buf + MSTART, msg, msg_len); 129 | 130 | // labelset = new_labelset(protocol_name, customization_label) 131 | if (labelset_new(labelset, &labelset_len, LABELSETMAXLEN, 132 | (unsigned char*)protocol_name, strlen(protocol_name), 133 | customization_label, customization_label_len) != 0) 134 | goto err; 135 | 136 | // labelset1 = add_label(labels, "1") 137 | // Bv = hash(hash(labelset1 || K) || M) 138 | // Kv = k * Bv 139 | labelset_add(labelset, &labelset_len, LABELSETMAXLEN, (unsigned char*)"1", 1); 140 | if (generalized_calculate_Bv(&Bv_point, labelset, labelset_len, 141 | eddsa_25519_pubkey_bytes, M_buf, MSTART, msg_len) != 0) 142 | goto err; 143 | ge_scalarmult(&Kv_point, eddsa_25519_privkey_scalar, &Bv_point); 144 | ge_p3_tobytes(Bv_bytes, &Bv_point); 145 | ge_p3_tobytes(Kv_bytes, &Kv_point); 146 | 147 | // labelset2 = add_label(labels, "2") 148 | // R, r = commit(labelset2, (Bv || Kv), (K,k), Z, M) 149 | labelset[labelset_len-1] = (unsigned char)'2'; 150 | memcpy(extra, Bv_bytes, POINTLEN); 151 | memcpy(extra + POINTLEN, Kv_bytes, POINTLEN); 152 | if (generalized_commit(R_bytes, r_scalar, 153 | labelset, labelset_len, 154 | extra, 2*POINTLEN, 155 | eddsa_25519_pubkey_bytes, eddsa_25519_privkey_scalar, 156 | random, M_buf, MSTART, msg_len) != 0) 157 | goto err; 158 | 159 | // Rv = r * Bv 160 | ge_scalarmult(&Rv_point, r_scalar, &Bv_point); 161 | ge_p3_tobytes(Rv_bytes, &Rv_point); 162 | 163 | // labelset3 = add_label(labels, "3") 164 | // h = challenge(labelset3, (Bv || Kv || Rv), R, K, M) 165 | labelset[labelset_len-1] = (unsigned char)'3'; 166 | memcpy(extra + 2*POINTLEN, Rv_bytes, POINTLEN); 167 | if (generalized_challenge(h_scalar, 168 | labelset, labelset_len, 169 | extra, 3*POINTLEN, 170 | R_bytes, eddsa_25519_pubkey_bytes, 171 | M_buf, MSTART, msg_len) != 0) 172 | goto err; 173 | 174 | // s = prove(r, k, h) 175 | if (generalized_prove(s_scalar, r_scalar, eddsa_25519_privkey_scalar, h_scalar) != 0) 176 | goto err; 177 | 178 | // return (Kv || h || s) 179 | memcpy(signature_out, Kv_bytes, POINTLEN); 180 | memcpy(signature_out + POINTLEN, h_scalar, SCALARLEN); 181 | memcpy(signature_out + POINTLEN + SCALARLEN, s_scalar, SCALARLEN); 182 | 183 | zeroize(r_scalar, SCALARLEN); 184 | zeroize_stack(); 185 | free(M_buf); 186 | return 0; 187 | 188 | err: 189 | zeroize(r_scalar, SCALARLEN); 190 | zeroize_stack(); 191 | free(M_buf); 192 | return -1; 193 | } 194 | 195 | int generalized_veddsa_25519_verify( 196 | unsigned char* vrf_out, 197 | const unsigned char* signature, 198 | const unsigned char* eddsa_25519_pubkey_bytes, 199 | const unsigned char* msg, 200 | const unsigned long msg_len, 201 | const unsigned char* customization_label, 202 | const unsigned long customization_label_len) 203 | { 204 | unsigned char labelset[LABELSETMAXLEN]; 205 | unsigned long labelset_len = 0; 206 | const unsigned char* Kv_bytes; 207 | const unsigned char* h_scalar; 208 | const unsigned char* s_scalar; 209 | ge_p3 Bv_point, K_point, Kv_point, cK_point, cKv_point; 210 | unsigned char Bv_bytes[POINTLEN]; 211 | unsigned char R_calc_bytes[POINTLEN]; 212 | unsigned char Rv_calc_bytes[POINTLEN]; 213 | unsigned char h_calc_scalar[SCALARLEN]; 214 | unsigned char extra[3*POINTLEN]; 215 | unsigned char* M_buf = NULL; 216 | char* protocol_name = "VEdDSA_25519_SHA512_Elligator2"; 217 | 218 | if (vrf_out == NULL) 219 | goto err; 220 | memset(vrf_out, 0, VRFOUTPUTLEN); 221 | 222 | if (signature == NULL) 223 | goto err; 224 | if (eddsa_25519_pubkey_bytes == NULL) 225 | goto err; 226 | if (msg == NULL) 227 | goto err; 228 | if (customization_label == NULL && customization_label_len != 0) 229 | goto err; 230 | if (customization_label_len > LABELMAXLEN) 231 | goto err; 232 | if (msg_len > MSGMAXLEN) 233 | goto err; 234 | 235 | if ((M_buf = malloc(msg_len + MSTART)) == 0) { 236 | goto err; 237 | } 238 | memcpy(M_buf + MSTART, msg, msg_len); 239 | 240 | Kv_bytes = signature; 241 | h_scalar = signature + POINTLEN; 242 | s_scalar = signature + POINTLEN + SCALARLEN; 243 | 244 | if (!point_isreduced(eddsa_25519_pubkey_bytes)) 245 | goto err; 246 | if (!point_isreduced(Kv_bytes)) 247 | goto err; 248 | if (!sc_isreduced(h_scalar)) 249 | goto err; 250 | if (!sc_isreduced(s_scalar)) 251 | goto err; 252 | 253 | // labelset = new_labelset(protocol_name, customization_label) 254 | if (labelset_new(labelset, &labelset_len, LABELSETMAXLEN, 255 | (unsigned char*)protocol_name, strlen(protocol_name), 256 | customization_label, customization_label_len) != 0) 257 | goto err; 258 | 259 | // labelset1 = add_label(labels, "1") 260 | // Bv = hash(hash(labelset1 || K) || M) 261 | labelset_add(labelset, &labelset_len, LABELSETMAXLEN, (unsigned char*)"1", 1); 262 | if (generalized_calculate_Bv(&Bv_point, labelset, labelset_len, 263 | eddsa_25519_pubkey_bytes, M_buf, MSTART, msg_len) != 0) 264 | goto err; 265 | ge_p3_tobytes(Bv_bytes, &Bv_point); 266 | 267 | // R = solve_commitment(B, s, K, h) 268 | if (generalized_solve_commitment(R_calc_bytes, &K_point, NULL, 269 | s_scalar, eddsa_25519_pubkey_bytes, h_scalar) != 0) 270 | goto err; 271 | 272 | // Rv = solve_commitment(Bv, s, Kv, h) 273 | if (generalized_solve_commitment(Rv_calc_bytes, &Kv_point, &Bv_point, 274 | s_scalar, Kv_bytes, h_scalar) != 0) 275 | goto err; 276 | 277 | ge_scalarmult_cofactor(&cK_point, &K_point); 278 | ge_scalarmult_cofactor(&cKv_point, &Kv_point); 279 | if (ge_isneutral(&cK_point) || ge_isneutral(&cKv_point) || ge_isneutral(&Bv_point)) 280 | goto err; 281 | 282 | // labelset3 = add_label(labels, "3") 283 | // h = challenge(labelset3, (Bv || Kv || Rv), R, K, M) 284 | labelset[labelset_len-1] = (unsigned char)'3'; 285 | memcpy(extra, Bv_bytes, POINTLEN); 286 | memcpy(extra + POINTLEN, Kv_bytes, POINTLEN); 287 | memcpy(extra + 2*POINTLEN, Rv_calc_bytes, POINTLEN); 288 | if (generalized_challenge(h_calc_scalar, 289 | labelset, labelset_len, 290 | extra, 3*POINTLEN, 291 | R_calc_bytes, eddsa_25519_pubkey_bytes, 292 | M_buf, MSTART, msg_len) != 0) 293 | goto err; 294 | 295 | // if bytes_equal(h, h') 296 | if (crypto_verify_32(h_scalar, h_calc_scalar) != 0) 297 | goto err; 298 | 299 | // labelset4 = add_label(labels, "4") 300 | // v = hash(labelset4 || c*Kv) 301 | labelset[labelset_len-1] = (unsigned char)'4'; 302 | if (generalized_calculate_vrf_output(vrf_out, labelset, labelset_len, &cKv_point) != 0) 303 | goto err; 304 | 305 | free(M_buf); 306 | return 0; 307 | 308 | err: 309 | free(M_buf); 310 | return -1; 311 | } 312 | 313 | -------------------------------------------------------------------------------- /curve/ed25519/additions/generalized/gen_veddsa.h: -------------------------------------------------------------------------------- 1 | #ifndef __GEN_VEDDSA_H__ 2 | #define __GEN_VEDDSA_H__ 3 | 4 | int generalized_veddsa_25519_sign( 5 | unsigned char* signature_out, 6 | const unsigned char* eddsa_25519_pubkey_bytes, 7 | const unsigned char* eddsa_25519_privkey_scalar, 8 | const unsigned char* msg, 9 | const unsigned long msg_len, 10 | const unsigned char* random, 11 | const unsigned char* customization_label, 12 | const unsigned long customization_label_len); 13 | 14 | int generalized_veddsa_25519_verify( 15 | unsigned char* vrf_out, 16 | const unsigned char* signature, 17 | const unsigned char* eddsa_25519_pubkey_bytes, 18 | const unsigned char* msg, 19 | const unsigned long msg_len, 20 | const unsigned char* customization_label, 21 | const unsigned long customization_label_len); 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /curve/ed25519/additions/generalized/gen_x.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "crypto_additions.h" 3 | #include "gen_x.h" 4 | #include "gen_constants.h" 5 | #include "gen_eddsa.h" 6 | #include "gen_veddsa.h" 7 | #include "gen_crypto_additions.h" 8 | #include "zeroize.h" 9 | 10 | static int convert_25519_pubkey(unsigned char* ed_pubkey_bytes, const unsigned char* x25519_pubkey_bytes) { 11 | fe u; 12 | fe y; 13 | 14 | /* Convert the X25519 public key into an Ed25519 public key. 15 | 16 | y = (u - 1) / (u + 1) 17 | 18 | NOTE: u=-1 is converted to y=0 since fe_invert is mod-exp 19 | */ 20 | if (!fe_isreduced(x25519_pubkey_bytes)) 21 | return -1; 22 | fe_frombytes(u, x25519_pubkey_bytes); 23 | fe_montx_to_edy(y, u); 24 | fe_tobytes(ed_pubkey_bytes, y); 25 | return 0; 26 | } 27 | 28 | static int calculate_25519_keypair(unsigned char* K_bytes, unsigned char* k_scalar, 29 | const unsigned char* x25519_privkey_scalar) 30 | { 31 | unsigned char kneg[SCALARLEN]; 32 | ge_p3 ed_pubkey_point; 33 | unsigned char sign_bit = 0; 34 | 35 | if (SCALARLEN != 32) 36 | return -1; 37 | 38 | /* Convert the Curve25519 privkey to an Ed25519 public key */ 39 | ge_scalarmult_base(&ed_pubkey_point, x25519_privkey_scalar); 40 | ge_p3_tobytes(K_bytes, &ed_pubkey_point); 41 | 42 | /* Force Edwards sign bit to zero */ 43 | sign_bit = (K_bytes[31] & 0x80) >> 7; 44 | memcpy(k_scalar, x25519_privkey_scalar, 32); 45 | sc_neg(kneg, k_scalar); 46 | sc_cmov(k_scalar, kneg, sign_bit); 47 | K_bytes[31] &= 0x7F; 48 | 49 | zeroize(kneg, SCALARLEN); 50 | return 0; 51 | } 52 | 53 | int generalized_xeddsa_25519_sign(unsigned char* signature_out, 54 | const unsigned char* x25519_privkey_scalar, 55 | const unsigned char* msg, const unsigned long msg_len, 56 | const unsigned char* random, 57 | const unsigned char* customization_label, 58 | const unsigned long customization_label_len) 59 | { 60 | unsigned char K_bytes[POINTLEN]; 61 | unsigned char k_scalar[SCALARLEN]; 62 | int retval = -1; 63 | 64 | if (calculate_25519_keypair(K_bytes, k_scalar, x25519_privkey_scalar) != 0) 65 | return -1; 66 | 67 | retval = generalized_eddsa_25519_sign(signature_out, 68 | K_bytes, k_scalar, 69 | msg, msg_len, random, 70 | customization_label, customization_label_len); 71 | zeroize(k_scalar, SCALARLEN); 72 | return retval; 73 | } 74 | 75 | int generalized_xveddsa_25519_sign( 76 | unsigned char* signature_out, 77 | const unsigned char* x25519_privkey_scalar, 78 | const unsigned char* msg, 79 | const unsigned long msg_len, 80 | const unsigned char* random, 81 | const unsigned char* customization_label, 82 | const unsigned long customization_label_len) 83 | { 84 | unsigned char K_bytes[POINTLEN]; 85 | unsigned char k_scalar[SCALARLEN]; 86 | int retval = -1; 87 | 88 | if (calculate_25519_keypair(K_bytes, k_scalar, x25519_privkey_scalar) != 0) 89 | return -1; 90 | 91 | retval = generalized_veddsa_25519_sign(signature_out, K_bytes, k_scalar, 92 | msg, msg_len, random, 93 | customization_label, customization_label_len); 94 | zeroize(k_scalar, SCALARLEN); 95 | return retval; 96 | } 97 | 98 | int generalized_xeddsa_25519_verify( 99 | const unsigned char* signature, 100 | const unsigned char* x25519_pubkey_bytes, 101 | const unsigned char* msg, 102 | const unsigned long msg_len, 103 | const unsigned char* customization_label, 104 | const unsigned long customization_label_len) 105 | { 106 | unsigned char K_bytes[POINTLEN]; 107 | 108 | if (convert_25519_pubkey(K_bytes, x25519_pubkey_bytes) != 0) 109 | return -1; 110 | 111 | return generalized_eddsa_25519_verify(signature, K_bytes, msg, msg_len, 112 | customization_label, customization_label_len); 113 | } 114 | 115 | int generalized_xveddsa_25519_verify( 116 | unsigned char* vrf_out, 117 | const unsigned char* signature, 118 | const unsigned char* x25519_pubkey_bytes, 119 | const unsigned char* msg, 120 | const unsigned long msg_len, 121 | const unsigned char* customization_label, 122 | const unsigned long customization_label_len) 123 | { 124 | unsigned char K_bytes[POINTLEN]; 125 | 126 | if (convert_25519_pubkey(K_bytes, x25519_pubkey_bytes) != 0) 127 | return -1; 128 | 129 | return generalized_veddsa_25519_verify(vrf_out, signature, K_bytes, msg, msg_len, 130 | customization_label, customization_label_len); 131 | } 132 | -------------------------------------------------------------------------------- /curve/ed25519/additions/generalized/gen_x.h: -------------------------------------------------------------------------------- 1 | #ifndef __GEN_X_H 2 | #define __GEN_X_H 3 | 4 | int generalized_xeddsa_25519_sign(unsigned char* signature_out, /* 64 bytes */ 5 | const unsigned char* x25519_privkey_scalar, /* 32 bytes */ 6 | const unsigned char* msg, const unsigned long msg_len, 7 | const unsigned char* random, /* 32 bytes */ 8 | const unsigned char* customization_label, 9 | const unsigned long customization_label_len); 10 | 11 | int generalized_xeddsa_25519_verify( 12 | const unsigned char* signature, /* 64 bytes */ 13 | const unsigned char* x25519_pubkey_bytes, /* 32 bytes */ 14 | const unsigned char* msg, 15 | const unsigned long msg_len, 16 | const unsigned char* customization_label, 17 | const unsigned long customization_label_len); 18 | 19 | int generalized_xveddsa_25519_sign( 20 | unsigned char* signature_out, /* 96 bytes */ 21 | const unsigned char* x25519_privkey_scalar, /* 32 bytes */ 22 | const unsigned char* msg, 23 | const unsigned long msg_len, 24 | const unsigned char* random, /* 32 bytes */ 25 | const unsigned char* customization_label, 26 | const unsigned long customization_label_len); 27 | 28 | int generalized_xveddsa_25519_verify( 29 | unsigned char* vrf_out, /* 32 bytes */ 30 | const unsigned char* signature, /* 96 bytes */ 31 | const unsigned char* x25519_pubkey_bytes, /* 32 bytes */ 32 | const unsigned char* msg, 33 | const unsigned long msg_len, 34 | const unsigned char* customization_label, 35 | const unsigned long customization_label_len); 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /curve/ed25519/additions/generalized/point_isreduced.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "fe.h" 3 | #include "crypto_additions.h" 4 | 5 | int point_isreduced(const unsigned char* p) 6 | { 7 | unsigned char strict[32]; 8 | 9 | memmove(strict, p, 32); 10 | strict[31] &= 0x7F; /* mask off sign bit */ 11 | return fe_isreduced(strict); 12 | } 13 | -------------------------------------------------------------------------------- /curve/ed25519/additions/generalized/sc_isreduced.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "fe.h" 3 | #include "sc.h" 4 | #include "crypto_additions.h" 5 | #include "crypto_verify_32.h" 6 | 7 | int sc_isreduced(const unsigned char* s) 8 | { 9 | unsigned char strict[64]; 10 | 11 | memset(strict, 0, 64); 12 | memmove(strict, s, 32); 13 | sc_reduce(strict); 14 | if (crypto_verify_32(strict, s) != 0) 15 | return 0; 16 | return 1; 17 | } 18 | -------------------------------------------------------------------------------- /curve/ed25519/additions/keygen.c: -------------------------------------------------------------------------------- 1 | #include "ge.h" 2 | #include "keygen.h" 3 | #include "crypto_additions.h" 4 | 5 | void curve25519_keygen(unsigned char* curve25519_pubkey_out, 6 | const unsigned char* curve25519_privkey_in) 7 | { 8 | /* Perform a fixed-base multiplication of the Edwards base point, 9 | (which is efficient due to precalculated tables), then convert 10 | to the Curve25519 montgomery-format public key. 11 | 12 | NOTE: y=1 is converted to u=0 since fe_invert is mod-exp 13 | */ 14 | 15 | ge_p3 ed; /* Ed25519 pubkey point */ 16 | fe u; 17 | 18 | ge_scalarmult_base(&ed, curve25519_privkey_in); 19 | ge_p3_to_montx(u, &ed); 20 | fe_tobytes(curve25519_pubkey_out, u); 21 | } 22 | -------------------------------------------------------------------------------- /curve/ed25519/additions/keygen.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef __KEYGEN_H__ 3 | #define __KEYGEN_H__ 4 | 5 | /* Sets and clears bits to make a random 32 bytes into a private key */ 6 | void sc_clamp(unsigned char* a); 7 | 8 | /* The private key should be 32 random bytes "clamped" by sc_clamp() */ 9 | void curve25519_keygen(unsigned char* curve25519_pubkey_out, /* 32 bytes */ 10 | const unsigned char* curve25519_privkey_in); /* 32 bytes */ 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /curve/ed25519/additions/open_modified.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "crypto_sign.h" 3 | #include "crypto_hash_sha512.h" 4 | #include "crypto_verify_32.h" 5 | #include "ge.h" 6 | #include "sc.h" 7 | #include "crypto_additions.h" 8 | 9 | int crypto_sign_open_modified( 10 | unsigned char *m, 11 | const unsigned char *sm,unsigned long long smlen, 12 | const unsigned char *pk 13 | ) 14 | { 15 | unsigned char pkcopy[32]; 16 | unsigned char rcopy[32]; 17 | unsigned char scopy[32]; 18 | unsigned char h[64]; 19 | unsigned char rcheck[32]; 20 | ge_p3 A; 21 | ge_p2 R; 22 | 23 | if (smlen < 64) goto badsig; 24 | if (sm[63] & 224) goto badsig; /* strict parsing of s */ 25 | if (ge_frombytes_negate_vartime(&A,pk) != 0) goto badsig; 26 | 27 | memmove(pkcopy,pk,32); 28 | memmove(rcopy,sm,32); 29 | memmove(scopy,sm + 32,32); 30 | 31 | memmove(m,sm,smlen); 32 | memmove(m + 32,pkcopy,32); 33 | crypto_hash_sha512(h,m,smlen); 34 | sc_reduce(h); 35 | 36 | ge_double_scalarmult_vartime(&R,h,&A,scopy); 37 | ge_tobytes(rcheck,&R); 38 | 39 | if (crypto_verify_32(rcheck,rcopy) == 0) { 40 | return 0; 41 | } 42 | 43 | badsig: 44 | return -1; 45 | } 46 | -------------------------------------------------------------------------------- /curve/ed25519/additions/sc_clamp.c: -------------------------------------------------------------------------------- 1 | #include "crypto_additions.h" 2 | 3 | void sc_clamp(unsigned char* a) 4 | { 5 | a[0] &= 248; 6 | a[31] &= 127; 7 | a[31] |= 64; 8 | } 9 | -------------------------------------------------------------------------------- /curve/ed25519/additions/sc_cmov.c: -------------------------------------------------------------------------------- 1 | #include "crypto_additions.h" 2 | 3 | /* 4 | Replace (f,g) with (g,g) if b == 1; 5 | replace (f,g) with (f,g) if b == 0. 6 | 7 | Preconditions: b in {0,1}. 8 | */ 9 | 10 | void sc_cmov(unsigned char* f, const unsigned char* g, unsigned char b) 11 | { 12 | int count=32; 13 | unsigned char x[32]; 14 | for (count=0; count < 32; count++) 15 | x[count] = f[count] ^ g[count]; 16 | b = -b; 17 | for (count=0; count < 32; count++) 18 | x[count] &= b; 19 | for (count=0; count < 32; count++) 20 | f[count] = f[count] ^ x[count]; 21 | } 22 | -------------------------------------------------------------------------------- /curve/ed25519/additions/sc_neg.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "crypto_additions.h" 3 | #include "sc.h" 4 | 5 | /* l = order of base point = 2^252 + 27742317777372353535851937790883648493 */ 6 | 7 | /* 8 | static unsigned char l[32] = {0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 9 | 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, 10 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 11 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0, 0x10}; 12 | */ 13 | 14 | static unsigned char lminus1[32] = {0xec, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 15 | 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, 16 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 17 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}; 18 | 19 | /* b = -a (mod l) */ 20 | void sc_neg(unsigned char *b, const unsigned char *a) 21 | { 22 | unsigned char zero[32]; 23 | memset(zero, 0, 32); 24 | sc_muladd(b, lminus1, a, zero); /* b = (-1)a + 0 (mod l) */ 25 | } 26 | -------------------------------------------------------------------------------- /curve/ed25519/additions/sign_modified.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "crypto_sign.h" 3 | #include "crypto_hash_sha512.h" 4 | #include "ge.h" 5 | #include "sc.h" 6 | #include "zeroize.h" 7 | #include "crypto_additions.h" 8 | 9 | /* NEW: Compare to pristine crypto_sign() 10 | Uses explicit private key for nonce derivation and as scalar, 11 | instead of deriving both from a master key. 12 | */ 13 | int crypto_sign_modified( 14 | unsigned char *sm, 15 | const unsigned char *m,unsigned long long mlen, 16 | const unsigned char *sk, const unsigned char* pk, 17 | const unsigned char* random 18 | ) 19 | { 20 | unsigned char nonce[64]; 21 | unsigned char hram[64]; 22 | ge_p3 R; 23 | int count=0; 24 | 25 | memmove(sm + 64,m,mlen); 26 | memmove(sm + 32,sk,32); /* NEW: Use privkey directly for nonce derivation */ 27 | 28 | /* NEW : add prefix to separate hash uses - see .h */ 29 | sm[0] = 0xFE; 30 | for (count = 1; count < 32; count++) 31 | sm[count] = 0xFF; 32 | 33 | /* NEW: add suffix of random data */ 34 | memmove(sm + mlen + 64, random, 64); 35 | 36 | crypto_hash_sha512(nonce,sm,mlen + 128); 37 | memmove(sm + 32,pk,32); 38 | 39 | sc_reduce(nonce); 40 | 41 | ge_scalarmult_base(&R,nonce); 42 | ge_p3_tobytes(sm,&R); 43 | 44 | crypto_hash_sha512(hram,sm,mlen + 64); 45 | sc_reduce(hram); 46 | sc_muladd(sm + 32,hram,sk,nonce); /* NEW: Use privkey directly */ 47 | 48 | /* Erase any traces of private scalar or 49 | nonce left in the stack from sc_muladd */ 50 | zeroize_stack(); 51 | zeroize(nonce, 64); 52 | return 0; 53 | } 54 | -------------------------------------------------------------------------------- /curve/ed25519/additions/utility.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "utility.h" 4 | 5 | void print_vector(const char* name, const unsigned char* v) 6 | { 7 | int count; 8 | printf("%s = \n", name); 9 | for (count = 0; count < 32; count++) 10 | printf("%02x ", v[count]); 11 | printf("\n"); 12 | } 13 | 14 | void print_bytes(const char* name, const unsigned char* v, int numbytes) 15 | { 16 | int count; 17 | printf("%s = \n", name); 18 | for (count = 0; count < numbytes; count++) 19 | printf("%02x ", v[count]); 20 | printf("\n"); 21 | } 22 | 23 | void print_fe(const char* name, const fe in) 24 | { 25 | unsigned char bytes[32]; 26 | fe_tobytes(bytes, in); 27 | print_vector(name, bytes); 28 | } 29 | 30 | -------------------------------------------------------------------------------- /curve/ed25519/additions/utility.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef __UTILITY_H__ 3 | #define __UTILITY_H__ 4 | 5 | #include "fe.h" 6 | 7 | void print_vector(const char* name, const unsigned char* v); 8 | void print_bytes(const char* name, const unsigned char* v, int numbytes); 9 | void print_fe(const char* name, const fe in); 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /curve/ed25519/additions/xeddsa.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "ge.h" 3 | #include "crypto_additions.h" 4 | #include "zeroize.h" 5 | #include "xeddsa.h" 6 | #include "crypto_verify_32.h" 7 | 8 | int xed25519_sign(unsigned char* signature_out, 9 | const unsigned char* curve25519_privkey, 10 | const unsigned char* msg, const unsigned long msg_len, 11 | const unsigned char* random) 12 | { 13 | unsigned char a[32], aneg[32]; 14 | unsigned char A[32]; 15 | ge_p3 ed_pubkey_point; 16 | unsigned char *sigbuf; /* working buffer */ 17 | unsigned char sign_bit = 0; 18 | 19 | if ((sigbuf = malloc(msg_len + 128)) == 0) { 20 | memset(signature_out, 0, 64); 21 | return -1; 22 | } 23 | 24 | /* Convert the Curve25519 privkey to an Ed25519 public key */ 25 | ge_scalarmult_base(&ed_pubkey_point, curve25519_privkey); 26 | ge_p3_tobytes(A, &ed_pubkey_point); 27 | 28 | /* Force Edwards sign bit to zero */ 29 | sign_bit = (A[31] & 0x80) >> 7; 30 | memcpy(a, curve25519_privkey, 32); 31 | sc_neg(aneg, a); 32 | sc_cmov(a, aneg, sign_bit); 33 | A[31] &= 0x7F; 34 | 35 | /* Perform an Ed25519 signature with explicit private key */ 36 | crypto_sign_modified(sigbuf, msg, msg_len, a, A, random); 37 | memmove(signature_out, sigbuf, 64); 38 | 39 | zeroize(a, 32); 40 | zeroize(aneg, 32); 41 | free(sigbuf); 42 | return 0; 43 | } 44 | 45 | int xed25519_verify(const unsigned char* signature, 46 | const unsigned char* curve25519_pubkey, 47 | const unsigned char* msg, const unsigned long msg_len) 48 | { 49 | fe u; 50 | fe y; 51 | unsigned char ed_pubkey[32]; 52 | unsigned char verifybuf[MAX_MSG_LEN + 64]; /* working buffer */ 53 | unsigned char verifybuf2[MAX_MSG_LEN + 64]; /* working buffer #2 */ 54 | 55 | if (msg_len > MAX_MSG_LEN) { 56 | return -1; 57 | } 58 | 59 | /* Convert the Curve25519 public key into an Ed25519 public key. 60 | 61 | y = (u - 1) / (u + 1) 62 | 63 | NOTE: u=-1 is converted to y=0 since fe_invert is mod-exp 64 | */ 65 | if (!fe_isreduced(curve25519_pubkey)) 66 | return -1; 67 | fe_frombytes(u, curve25519_pubkey); 68 | fe_montx_to_edy(y, u); 69 | fe_tobytes(ed_pubkey, y); 70 | 71 | memmove(verifybuf, signature, 64); 72 | memmove(verifybuf+64, msg, msg_len); 73 | 74 | /* Then perform a normal Ed25519 verification, return 0 on success */ 75 | /* The below call has a strange API: */ 76 | /* verifybuf = R || S || message */ 77 | /* verifybuf2 = internal to next call gets a copy of verifybuf, S gets 78 | replaced with pubkey for hashing */ 79 | return crypto_sign_open_modified(verifybuf2, verifybuf, 64 + msg_len, ed_pubkey); 80 | } 81 | -------------------------------------------------------------------------------- /curve/ed25519/additions/xeddsa.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef __XEDDSA_H__ 3 | #define __XEDDSA_H__ 4 | 5 | /* returns 0 on success */ 6 | int xed25519_sign(unsigned char* signature_out, /* 64 bytes */ 7 | const unsigned char* curve25519_privkey, /* 32 bytes */ 8 | const unsigned char* msg, const unsigned long msg_len, /* <= 256 bytes */ 9 | const unsigned char* random); /* 64 bytes */ 10 | 11 | /* returns 0 on success */ 12 | int xed25519_verify(const unsigned char* signature, /* 64 bytes */ 13 | const unsigned char* curve25519_pubkey, /* 32 bytes */ 14 | const unsigned char* msg, const unsigned long msg_len); /* <= 256 bytes */ 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /curve/ed25519/additions/zeroize.c: -------------------------------------------------------------------------------- 1 | #include "zeroize.h" 2 | 3 | void zeroize(unsigned char* b, size_t len) 4 | { 5 | size_t count = 0; 6 | volatile unsigned char *p = b; 7 | 8 | for (count = 0; count < len; count++) 9 | p[count] = 0; 10 | } 11 | 12 | void zeroize_stack() 13 | { 14 | unsigned char m[ZEROIZE_STACK_SIZE]; 15 | zeroize(m, ZEROIZE_STACK_SIZE); 16 | } 17 | -------------------------------------------------------------------------------- /curve/ed25519/additions/zeroize.h: -------------------------------------------------------------------------------- 1 | #ifndef __ZEROIZE_H__ 2 | #define __ZEROIZE_H__ 3 | 4 | #include 5 | 6 | #define ZEROIZE_STACK_SIZE 1024 7 | 8 | void zeroize(unsigned char* b, size_t len); 9 | 10 | void zeroize_stack(); 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /curve/ed25519/api.h: -------------------------------------------------------------------------------- 1 | #define CRYPTO_SECRETKEYBYTES 64 2 | #define CRYPTO_PUBLICKEYBYTES 32 3 | #define CRYPTO_BYTES 64 4 | #define CRYPTO_DETERMINISTIC 1 5 | -------------------------------------------------------------------------------- /curve/ed25519/base2.h: -------------------------------------------------------------------------------- 1 | { 2 | { 25967493,-14356035,29566456,3660896,-12694345,4014787,27544626,-11754271,-6079156,2047605 }, 3 | { -12545711,934262,-2722910,3049990,-727428,9406986,12720692,5043384,19500929,-15469378 }, 4 | { -8738181,4489570,9688441,-14785194,10184609,-12363380,29287919,11864899,-24514362,-4438546 }, 5 | }, 6 | { 7 | { 15636291,-9688557,24204773,-7912398,616977,-16685262,27787600,-14772189,28944400,-1550024 }, 8 | { 16568933,4717097,-11556148,-1102322,15682896,-11807043,16354577,-11775962,7689662,11199574 }, 9 | { 30464156,-5976125,-11779434,-15670865,23220365,15915852,7512774,10017326,-17749093,-9920357 }, 10 | }, 11 | { 12 | { 10861363,11473154,27284546,1981175,-30064349,12577861,32867885,14515107,-15438304,10819380 }, 13 | { 4708026,6336745,20377586,9066809,-11272109,6594696,-25653668,12483688,-12668491,5581306 }, 14 | { 19563160,16186464,-29386857,4097519,10237984,-4348115,28542350,13850243,-23678021,-15815942 }, 15 | }, 16 | { 17 | { 5153746,9909285,1723747,-2777874,30523605,5516873,19480852,5230134,-23952439,-15175766 }, 18 | { -30269007,-3463509,7665486,10083793,28475525,1649722,20654025,16520125,30598449,7715701 }, 19 | { 28881845,14381568,9657904,3680757,-20181635,7843316,-31400660,1370708,29794553,-1409300 }, 20 | }, 21 | { 22 | { -22518993,-6692182,14201702,-8745502,-23510406,8844726,18474211,-1361450,-13062696,13821877 }, 23 | { -6455177,-7839871,3374702,-4740862,-27098617,-10571707,31655028,-7212327,18853322,-14220951 }, 24 | { 4566830,-12963868,-28974889,-12240689,-7602672,-2830569,-8514358,-10431137,2207753,-3209784 }, 25 | }, 26 | { 27 | { -25154831,-4185821,29681144,7868801,-6854661,-9423865,-12437364,-663000,-31111463,-16132436 }, 28 | { 25576264,-2703214,7349804,-11814844,16472782,9300885,3844789,15725684,171356,6466918 }, 29 | { 23103977,13316479,9739013,-16149481,817875,-15038942,8965339,-14088058,-30714912,16193877 }, 30 | }, 31 | { 32 | { -33521811,3180713,-2394130,14003687,-16903474,-16270840,17238398,4729455,-18074513,9256800 }, 33 | { -25182317,-4174131,32336398,5036987,-21236817,11360617,22616405,9761698,-19827198,630305 }, 34 | { -13720693,2639453,-24237460,-7406481,9494427,-5774029,-6554551,-15960994,-2449256,-14291300 }, 35 | }, 36 | { 37 | { -3151181,-5046075,9282714,6866145,-31907062,-863023,-18940575,15033784,25105118,-7894876 }, 38 | { -24326370,15950226,-31801215,-14592823,-11662737,-5090925,1573892,-2625887,2198790,-15804619 }, 39 | { -3099351,10324967,-2241613,7453183,-5446979,-2735503,-13812022,-16236442,-32461234,-12290683 }, 40 | }, 41 | -------------------------------------------------------------------------------- /curve/ed25519/d.h: -------------------------------------------------------------------------------- 1 | -10913610,13857413,-15372611,6949391,114729,-8787816,-6275908,-3247719,-18696448,-12055116 2 | -------------------------------------------------------------------------------- /curve/ed25519/d2.h: -------------------------------------------------------------------------------- 1 | -21827239,-5839606,-30745221,13898782,229458,15978800,-12551817,-6495438,29715968,9444199 2 | -------------------------------------------------------------------------------- /curve/ed25519/fe.h: -------------------------------------------------------------------------------- 1 | #ifndef FE_H 2 | #define FE_H 3 | 4 | #include "crypto_int32.h" 5 | 6 | typedef crypto_int32 fe[10]; 7 | 8 | /* 9 | fe means field element. 10 | Here the field is \Z/(2^255-19). 11 | An element t, entries t[0]...t[9], represents the integer 12 | t[0]+2^26 t[1]+2^51 t[2]+2^77 t[3]+2^102 t[4]+...+2^230 t[9]. 13 | Bounds on each t[i] vary depending on context. 14 | */ 15 | 16 | #define fe_frombytes crypto_sign_ed25519_ref10_fe_frombytes 17 | #define fe_tobytes crypto_sign_ed25519_ref10_fe_tobytes 18 | #define fe_copy crypto_sign_ed25519_ref10_fe_copy 19 | #define fe_isnonzero crypto_sign_ed25519_ref10_fe_isnonzero 20 | #define fe_isnegative crypto_sign_ed25519_ref10_fe_isnegative 21 | #define fe_0 crypto_sign_ed25519_ref10_fe_0 22 | #define fe_1 crypto_sign_ed25519_ref10_fe_1 23 | #define fe_cswap crypto_sign_ed25519_ref10_fe_cswap 24 | #define fe_cmov crypto_sign_ed25519_ref10_fe_cmov 25 | #define fe_add crypto_sign_ed25519_ref10_fe_add 26 | #define fe_sub crypto_sign_ed25519_ref10_fe_sub 27 | #define fe_neg crypto_sign_ed25519_ref10_fe_neg 28 | #define fe_mul crypto_sign_ed25519_ref10_fe_mul 29 | #define fe_sq crypto_sign_ed25519_ref10_fe_sq 30 | #define fe_sq2 crypto_sign_ed25519_ref10_fe_sq2 31 | #define fe_mul121666 crypto_sign_ed25519_ref10_fe_mul121666 32 | #define fe_invert crypto_sign_ed25519_ref10_fe_invert 33 | #define fe_pow22523 crypto_sign_ed25519_ref10_fe_pow22523 34 | 35 | extern void fe_frombytes(fe,const unsigned char *); 36 | extern void fe_tobytes(unsigned char *,const fe); 37 | 38 | extern void fe_copy(fe,const fe); 39 | extern int fe_isnonzero(const fe); 40 | extern int fe_isnegative(const fe); 41 | extern void fe_0(fe); 42 | extern void fe_1(fe); 43 | extern void fe_cswap(fe,fe,unsigned int); 44 | extern void fe_cmov(fe,const fe,unsigned int); 45 | 46 | extern void fe_add(fe,const fe,const fe); 47 | extern void fe_sub(fe,const fe,const fe); 48 | extern void fe_neg(fe,const fe); 49 | extern void fe_mul(fe,const fe,const fe); 50 | extern void fe_sq(fe,const fe); 51 | extern void fe_sq2(fe,const fe); 52 | extern void fe_mul121666(fe,const fe); 53 | extern void fe_invert(fe,const fe); 54 | extern void fe_pow22523(fe,const fe); 55 | 56 | #endif 57 | -------------------------------------------------------------------------------- /curve/ed25519/fe_0.c: -------------------------------------------------------------------------------- 1 | #include "fe.h" 2 | 3 | /* 4 | h = 0 5 | */ 6 | 7 | void fe_0(fe h) 8 | { 9 | h[0] = 0; 10 | h[1] = 0; 11 | h[2] = 0; 12 | h[3] = 0; 13 | h[4] = 0; 14 | h[5] = 0; 15 | h[6] = 0; 16 | h[7] = 0; 17 | h[8] = 0; 18 | h[9] = 0; 19 | } 20 | -------------------------------------------------------------------------------- /curve/ed25519/fe_1.c: -------------------------------------------------------------------------------- 1 | #include "fe.h" 2 | 3 | /* 4 | h = 1 5 | */ 6 | 7 | void fe_1(fe h) 8 | { 9 | h[0] = 1; 10 | h[1] = 0; 11 | h[2] = 0; 12 | h[3] = 0; 13 | h[4] = 0; 14 | h[5] = 0; 15 | h[6] = 0; 16 | h[7] = 0; 17 | h[8] = 0; 18 | h[9] = 0; 19 | } 20 | -------------------------------------------------------------------------------- /curve/ed25519/fe_add.c: -------------------------------------------------------------------------------- 1 | #include "fe.h" 2 | 3 | /* 4 | h = f + g 5 | Can overlap h with f or g. 6 | 7 | Preconditions: 8 | |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. 9 | |g| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. 10 | 11 | Postconditions: 12 | |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. 13 | */ 14 | 15 | void fe_add(fe h,const fe f,const fe g) 16 | { 17 | crypto_int32 f0 = f[0]; 18 | crypto_int32 f1 = f[1]; 19 | crypto_int32 f2 = f[2]; 20 | crypto_int32 f3 = f[3]; 21 | crypto_int32 f4 = f[4]; 22 | crypto_int32 f5 = f[5]; 23 | crypto_int32 f6 = f[6]; 24 | crypto_int32 f7 = f[7]; 25 | crypto_int32 f8 = f[8]; 26 | crypto_int32 f9 = f[9]; 27 | crypto_int32 g0 = g[0]; 28 | crypto_int32 g1 = g[1]; 29 | crypto_int32 g2 = g[2]; 30 | crypto_int32 g3 = g[3]; 31 | crypto_int32 g4 = g[4]; 32 | crypto_int32 g5 = g[5]; 33 | crypto_int32 g6 = g[6]; 34 | crypto_int32 g7 = g[7]; 35 | crypto_int32 g8 = g[8]; 36 | crypto_int32 g9 = g[9]; 37 | crypto_int32 h0 = f0 + g0; 38 | crypto_int32 h1 = f1 + g1; 39 | crypto_int32 h2 = f2 + g2; 40 | crypto_int32 h3 = f3 + g3; 41 | crypto_int32 h4 = f4 + g4; 42 | crypto_int32 h5 = f5 + g5; 43 | crypto_int32 h6 = f6 + g6; 44 | crypto_int32 h7 = f7 + g7; 45 | crypto_int32 h8 = f8 + g8; 46 | crypto_int32 h9 = f9 + g9; 47 | h[0] = h0; 48 | h[1] = h1; 49 | h[2] = h2; 50 | h[3] = h3; 51 | h[4] = h4; 52 | h[5] = h5; 53 | h[6] = h6; 54 | h[7] = h7; 55 | h[8] = h8; 56 | h[9] = h9; 57 | } 58 | -------------------------------------------------------------------------------- /curve/ed25519/fe_cmov.c: -------------------------------------------------------------------------------- 1 | #include "fe.h" 2 | 3 | /* 4 | Replace (f,g) with (g,g) if b == 1; 5 | replace (f,g) with (f,g) if b == 0. 6 | 7 | Preconditions: b in {0,1}. 8 | */ 9 | 10 | void fe_cmov(fe f,const fe g,unsigned int b) 11 | { 12 | crypto_int32 f0 = f[0]; 13 | crypto_int32 f1 = f[1]; 14 | crypto_int32 f2 = f[2]; 15 | crypto_int32 f3 = f[3]; 16 | crypto_int32 f4 = f[4]; 17 | crypto_int32 f5 = f[5]; 18 | crypto_int32 f6 = f[6]; 19 | crypto_int32 f7 = f[7]; 20 | crypto_int32 f8 = f[8]; 21 | crypto_int32 f9 = f[9]; 22 | crypto_int32 g0 = g[0]; 23 | crypto_int32 g1 = g[1]; 24 | crypto_int32 g2 = g[2]; 25 | crypto_int32 g3 = g[3]; 26 | crypto_int32 g4 = g[4]; 27 | crypto_int32 g5 = g[5]; 28 | crypto_int32 g6 = g[6]; 29 | crypto_int32 g7 = g[7]; 30 | crypto_int32 g8 = g[8]; 31 | crypto_int32 g9 = g[9]; 32 | crypto_int32 x0 = f0 ^ g0; 33 | crypto_int32 x1 = f1 ^ g1; 34 | crypto_int32 x2 = f2 ^ g2; 35 | crypto_int32 x3 = f3 ^ g3; 36 | crypto_int32 x4 = f4 ^ g4; 37 | crypto_int32 x5 = f5 ^ g5; 38 | crypto_int32 x6 = f6 ^ g6; 39 | crypto_int32 x7 = f7 ^ g7; 40 | crypto_int32 x8 = f8 ^ g8; 41 | crypto_int32 x9 = f9 ^ g9; 42 | b = -b; 43 | x0 &= b; 44 | x1 &= b; 45 | x2 &= b; 46 | x3 &= b; 47 | x4 &= b; 48 | x5 &= b; 49 | x6 &= b; 50 | x7 &= b; 51 | x8 &= b; 52 | x9 &= b; 53 | f[0] = f0 ^ x0; 54 | f[1] = f1 ^ x1; 55 | f[2] = f2 ^ x2; 56 | f[3] = f3 ^ x3; 57 | f[4] = f4 ^ x4; 58 | f[5] = f5 ^ x5; 59 | f[6] = f6 ^ x6; 60 | f[7] = f7 ^ x7; 61 | f[8] = f8 ^ x8; 62 | f[9] = f9 ^ x9; 63 | } 64 | -------------------------------------------------------------------------------- /curve/ed25519/fe_copy.c: -------------------------------------------------------------------------------- 1 | #include "fe.h" 2 | 3 | /* 4 | h = f 5 | */ 6 | 7 | void fe_copy(fe h,const fe f) 8 | { 9 | crypto_int32 f0 = f[0]; 10 | crypto_int32 f1 = f[1]; 11 | crypto_int32 f2 = f[2]; 12 | crypto_int32 f3 = f[3]; 13 | crypto_int32 f4 = f[4]; 14 | crypto_int32 f5 = f[5]; 15 | crypto_int32 f6 = f[6]; 16 | crypto_int32 f7 = f[7]; 17 | crypto_int32 f8 = f[8]; 18 | crypto_int32 f9 = f[9]; 19 | h[0] = f0; 20 | h[1] = f1; 21 | h[2] = f2; 22 | h[3] = f3; 23 | h[4] = f4; 24 | h[5] = f5; 25 | h[6] = f6; 26 | h[7] = f7; 27 | h[8] = f8; 28 | h[9] = f9; 29 | } 30 | -------------------------------------------------------------------------------- /curve/ed25519/fe_frombytes.c: -------------------------------------------------------------------------------- 1 | #include "fe.h" 2 | #include "crypto_int64.h" 3 | #include "crypto_uint64.h" 4 | 5 | static crypto_uint64 load_3(const unsigned char *in) 6 | { 7 | crypto_uint64 result; 8 | result = (crypto_uint64) in[0]; 9 | result |= ((crypto_uint64) in[1]) << 8; 10 | result |= ((crypto_uint64) in[2]) << 16; 11 | return result; 12 | } 13 | 14 | static crypto_uint64 load_4(const unsigned char *in) 15 | { 16 | crypto_uint64 result; 17 | result = (crypto_uint64) in[0]; 18 | result |= ((crypto_uint64) in[1]) << 8; 19 | result |= ((crypto_uint64) in[2]) << 16; 20 | result |= ((crypto_uint64) in[3]) << 24; 21 | return result; 22 | } 23 | 24 | /* 25 | Ignores top bit of h. 26 | */ 27 | 28 | void fe_frombytes(fe h,const unsigned char *s) 29 | { 30 | crypto_int64 h0 = load_4(s); 31 | crypto_int64 h1 = load_3(s + 4) << 6; 32 | crypto_int64 h2 = load_3(s + 7) << 5; 33 | crypto_int64 h3 = load_3(s + 10) << 3; 34 | crypto_int64 h4 = load_3(s + 13) << 2; 35 | crypto_int64 h5 = load_4(s + 16); 36 | crypto_int64 h6 = load_3(s + 20) << 7; 37 | crypto_int64 h7 = load_3(s + 23) << 5; 38 | crypto_int64 h8 = load_3(s + 26) << 4; 39 | crypto_int64 h9 = (load_3(s + 29) & 8388607) << 2; 40 | crypto_int64 carry0; 41 | crypto_int64 carry1; 42 | crypto_int64 carry2; 43 | crypto_int64 carry3; 44 | crypto_int64 carry4; 45 | crypto_int64 carry5; 46 | crypto_int64 carry6; 47 | crypto_int64 carry7; 48 | crypto_int64 carry8; 49 | crypto_int64 carry9; 50 | 51 | carry9 = (h9 + (crypto_int64) (1<<24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25; 52 | carry1 = (h1 + (crypto_int64) (1<<24)) >> 25; h2 += carry1; h1 -= carry1 << 25; 53 | carry3 = (h3 + (crypto_int64) (1<<24)) >> 25; h4 += carry3; h3 -= carry3 << 25; 54 | carry5 = (h5 + (crypto_int64) (1<<24)) >> 25; h6 += carry5; h5 -= carry5 << 25; 55 | carry7 = (h7 + (crypto_int64) (1<<24)) >> 25; h8 += carry7; h7 -= carry7 << 25; 56 | 57 | carry0 = (h0 + (crypto_int64) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26; 58 | carry2 = (h2 + (crypto_int64) (1<<25)) >> 26; h3 += carry2; h2 -= carry2 << 26; 59 | carry4 = (h4 + (crypto_int64) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26; 60 | carry6 = (h6 + (crypto_int64) (1<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26; 61 | carry8 = (h8 + (crypto_int64) (1<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26; 62 | 63 | h[0] = h0; 64 | h[1] = h1; 65 | h[2] = h2; 66 | h[3] = h3; 67 | h[4] = h4; 68 | h[5] = h5; 69 | h[6] = h6; 70 | h[7] = h7; 71 | h[8] = h8; 72 | h[9] = h9; 73 | } 74 | -------------------------------------------------------------------------------- /curve/ed25519/fe_invert.c: -------------------------------------------------------------------------------- 1 | #include "fe.h" 2 | 3 | void fe_invert(fe out,const fe z) 4 | { 5 | fe t0; 6 | fe t1; 7 | fe t2; 8 | fe t3; 9 | int i; 10 | 11 | #include "pow225521.h" 12 | 13 | return; 14 | } 15 | -------------------------------------------------------------------------------- /curve/ed25519/fe_isnegative.c: -------------------------------------------------------------------------------- 1 | #include "fe.h" 2 | 3 | /* 4 | return 1 if f is in {1,3,5,...,q-2} 5 | return 0 if f is in {0,2,4,...,q-1} 6 | 7 | Preconditions: 8 | |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. 9 | */ 10 | 11 | int fe_isnegative(const fe f) 12 | { 13 | unsigned char s[32]; 14 | fe_tobytes(s,f); 15 | return s[0] & 1; 16 | } 17 | -------------------------------------------------------------------------------- /curve/ed25519/fe_isnonzero.c: -------------------------------------------------------------------------------- 1 | #include "fe.h" 2 | #include "crypto_verify_32.h" 3 | 4 | /* 5 | return nonzero if f == 0 6 | return 0 if f != 0 7 | 8 | Preconditions: 9 | |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. 10 | */ 11 | 12 | /* TREVOR'S COMMENT 13 | * 14 | * I think the above comment is wrong. Instead: 15 | * 16 | * return 0 if f == 0 17 | * return -1 if f != 0 18 | * 19 | * */ 20 | 21 | static const unsigned char zero[32]; 22 | 23 | int fe_isnonzero(const fe f) 24 | { 25 | unsigned char s[32]; 26 | fe_tobytes(s,f); 27 | return crypto_verify_32(s,zero); 28 | } 29 | -------------------------------------------------------------------------------- /curve/ed25519/fe_mul.c: -------------------------------------------------------------------------------- 1 | #include "fe.h" 2 | #include "crypto_int64.h" 3 | 4 | /* 5 | h = f * g 6 | Can overlap h with f or g. 7 | 8 | Preconditions: 9 | |f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc. 10 | |g| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc. 11 | 12 | Postconditions: 13 | |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc. 14 | */ 15 | 16 | /* 17 | Notes on implementation strategy: 18 | 19 | Using schoolbook multiplication. 20 | Karatsuba would save a little in some cost models. 21 | 22 | Most multiplications by 2 and 19 are 32-bit precomputations; 23 | cheaper than 64-bit postcomputations. 24 | 25 | There is one remaining multiplication by 19 in the carry chain; 26 | one *19 precomputation can be merged into this, 27 | but the resulting data flow is considerably less clean. 28 | 29 | There are 12 carries below. 30 | 10 of them are 2-way parallelizable and vectorizable. 31 | Can get away with 11 carries, but then data flow is much deeper. 32 | 33 | With tighter constraints on inputs can squeeze carries into int32. 34 | */ 35 | 36 | void fe_mul(fe h,const fe f,const fe g) 37 | { 38 | crypto_int32 f0 = f[0]; 39 | crypto_int32 f1 = f[1]; 40 | crypto_int32 f2 = f[2]; 41 | crypto_int32 f3 = f[3]; 42 | crypto_int32 f4 = f[4]; 43 | crypto_int32 f5 = f[5]; 44 | crypto_int32 f6 = f[6]; 45 | crypto_int32 f7 = f[7]; 46 | crypto_int32 f8 = f[8]; 47 | crypto_int32 f9 = f[9]; 48 | crypto_int32 g0 = g[0]; 49 | crypto_int32 g1 = g[1]; 50 | crypto_int32 g2 = g[2]; 51 | crypto_int32 g3 = g[3]; 52 | crypto_int32 g4 = g[4]; 53 | crypto_int32 g5 = g[5]; 54 | crypto_int32 g6 = g[6]; 55 | crypto_int32 g7 = g[7]; 56 | crypto_int32 g8 = g[8]; 57 | crypto_int32 g9 = g[9]; 58 | crypto_int32 g1_19 = 19 * g1; /* 1.959375*2^29 */ 59 | crypto_int32 g2_19 = 19 * g2; /* 1.959375*2^30; still ok */ 60 | crypto_int32 g3_19 = 19 * g3; 61 | crypto_int32 g4_19 = 19 * g4; 62 | crypto_int32 g5_19 = 19 * g5; 63 | crypto_int32 g6_19 = 19 * g6; 64 | crypto_int32 g7_19 = 19 * g7; 65 | crypto_int32 g8_19 = 19 * g8; 66 | crypto_int32 g9_19 = 19 * g9; 67 | crypto_int32 f1_2 = 2 * f1; 68 | crypto_int32 f3_2 = 2 * f3; 69 | crypto_int32 f5_2 = 2 * f5; 70 | crypto_int32 f7_2 = 2 * f7; 71 | crypto_int32 f9_2 = 2 * f9; 72 | crypto_int64 f0g0 = f0 * (crypto_int64) g0; 73 | crypto_int64 f0g1 = f0 * (crypto_int64) g1; 74 | crypto_int64 f0g2 = f0 * (crypto_int64) g2; 75 | crypto_int64 f0g3 = f0 * (crypto_int64) g3; 76 | crypto_int64 f0g4 = f0 * (crypto_int64) g4; 77 | crypto_int64 f0g5 = f0 * (crypto_int64) g5; 78 | crypto_int64 f0g6 = f0 * (crypto_int64) g6; 79 | crypto_int64 f0g7 = f0 * (crypto_int64) g7; 80 | crypto_int64 f0g8 = f0 * (crypto_int64) g8; 81 | crypto_int64 f0g9 = f0 * (crypto_int64) g9; 82 | crypto_int64 f1g0 = f1 * (crypto_int64) g0; 83 | crypto_int64 f1g1_2 = f1_2 * (crypto_int64) g1; 84 | crypto_int64 f1g2 = f1 * (crypto_int64) g2; 85 | crypto_int64 f1g3_2 = f1_2 * (crypto_int64) g3; 86 | crypto_int64 f1g4 = f1 * (crypto_int64) g4; 87 | crypto_int64 f1g5_2 = f1_2 * (crypto_int64) g5; 88 | crypto_int64 f1g6 = f1 * (crypto_int64) g6; 89 | crypto_int64 f1g7_2 = f1_2 * (crypto_int64) g7; 90 | crypto_int64 f1g8 = f1 * (crypto_int64) g8; 91 | crypto_int64 f1g9_38 = f1_2 * (crypto_int64) g9_19; 92 | crypto_int64 f2g0 = f2 * (crypto_int64) g0; 93 | crypto_int64 f2g1 = f2 * (crypto_int64) g1; 94 | crypto_int64 f2g2 = f2 * (crypto_int64) g2; 95 | crypto_int64 f2g3 = f2 * (crypto_int64) g3; 96 | crypto_int64 f2g4 = f2 * (crypto_int64) g4; 97 | crypto_int64 f2g5 = f2 * (crypto_int64) g5; 98 | crypto_int64 f2g6 = f2 * (crypto_int64) g6; 99 | crypto_int64 f2g7 = f2 * (crypto_int64) g7; 100 | crypto_int64 f2g8_19 = f2 * (crypto_int64) g8_19; 101 | crypto_int64 f2g9_19 = f2 * (crypto_int64) g9_19; 102 | crypto_int64 f3g0 = f3 * (crypto_int64) g0; 103 | crypto_int64 f3g1_2 = f3_2 * (crypto_int64) g1; 104 | crypto_int64 f3g2 = f3 * (crypto_int64) g2; 105 | crypto_int64 f3g3_2 = f3_2 * (crypto_int64) g3; 106 | crypto_int64 f3g4 = f3 * (crypto_int64) g4; 107 | crypto_int64 f3g5_2 = f3_2 * (crypto_int64) g5; 108 | crypto_int64 f3g6 = f3 * (crypto_int64) g6; 109 | crypto_int64 f3g7_38 = f3_2 * (crypto_int64) g7_19; 110 | crypto_int64 f3g8_19 = f3 * (crypto_int64) g8_19; 111 | crypto_int64 f3g9_38 = f3_2 * (crypto_int64) g9_19; 112 | crypto_int64 f4g0 = f4 * (crypto_int64) g0; 113 | crypto_int64 f4g1 = f4 * (crypto_int64) g1; 114 | crypto_int64 f4g2 = f4 * (crypto_int64) g2; 115 | crypto_int64 f4g3 = f4 * (crypto_int64) g3; 116 | crypto_int64 f4g4 = f4 * (crypto_int64) g4; 117 | crypto_int64 f4g5 = f4 * (crypto_int64) g5; 118 | crypto_int64 f4g6_19 = f4 * (crypto_int64) g6_19; 119 | crypto_int64 f4g7_19 = f4 * (crypto_int64) g7_19; 120 | crypto_int64 f4g8_19 = f4 * (crypto_int64) g8_19; 121 | crypto_int64 f4g9_19 = f4 * (crypto_int64) g9_19; 122 | crypto_int64 f5g0 = f5 * (crypto_int64) g0; 123 | crypto_int64 f5g1_2 = f5_2 * (crypto_int64) g1; 124 | crypto_int64 f5g2 = f5 * (crypto_int64) g2; 125 | crypto_int64 f5g3_2 = f5_2 * (crypto_int64) g3; 126 | crypto_int64 f5g4 = f5 * (crypto_int64) g4; 127 | crypto_int64 f5g5_38 = f5_2 * (crypto_int64) g5_19; 128 | crypto_int64 f5g6_19 = f5 * (crypto_int64) g6_19; 129 | crypto_int64 f5g7_38 = f5_2 * (crypto_int64) g7_19; 130 | crypto_int64 f5g8_19 = f5 * (crypto_int64) g8_19; 131 | crypto_int64 f5g9_38 = f5_2 * (crypto_int64) g9_19; 132 | crypto_int64 f6g0 = f6 * (crypto_int64) g0; 133 | crypto_int64 f6g1 = f6 * (crypto_int64) g1; 134 | crypto_int64 f6g2 = f6 * (crypto_int64) g2; 135 | crypto_int64 f6g3 = f6 * (crypto_int64) g3; 136 | crypto_int64 f6g4_19 = f6 * (crypto_int64) g4_19; 137 | crypto_int64 f6g5_19 = f6 * (crypto_int64) g5_19; 138 | crypto_int64 f6g6_19 = f6 * (crypto_int64) g6_19; 139 | crypto_int64 f6g7_19 = f6 * (crypto_int64) g7_19; 140 | crypto_int64 f6g8_19 = f6 * (crypto_int64) g8_19; 141 | crypto_int64 f6g9_19 = f6 * (crypto_int64) g9_19; 142 | crypto_int64 f7g0 = f7 * (crypto_int64) g0; 143 | crypto_int64 f7g1_2 = f7_2 * (crypto_int64) g1; 144 | crypto_int64 f7g2 = f7 * (crypto_int64) g2; 145 | crypto_int64 f7g3_38 = f7_2 * (crypto_int64) g3_19; 146 | crypto_int64 f7g4_19 = f7 * (crypto_int64) g4_19; 147 | crypto_int64 f7g5_38 = f7_2 * (crypto_int64) g5_19; 148 | crypto_int64 f7g6_19 = f7 * (crypto_int64) g6_19; 149 | crypto_int64 f7g7_38 = f7_2 * (crypto_int64) g7_19; 150 | crypto_int64 f7g8_19 = f7 * (crypto_int64) g8_19; 151 | crypto_int64 f7g9_38 = f7_2 * (crypto_int64) g9_19; 152 | crypto_int64 f8g0 = f8 * (crypto_int64) g0; 153 | crypto_int64 f8g1 = f8 * (crypto_int64) g1; 154 | crypto_int64 f8g2_19 = f8 * (crypto_int64) g2_19; 155 | crypto_int64 f8g3_19 = f8 * (crypto_int64) g3_19; 156 | crypto_int64 f8g4_19 = f8 * (crypto_int64) g4_19; 157 | crypto_int64 f8g5_19 = f8 * (crypto_int64) g5_19; 158 | crypto_int64 f8g6_19 = f8 * (crypto_int64) g6_19; 159 | crypto_int64 f8g7_19 = f8 * (crypto_int64) g7_19; 160 | crypto_int64 f8g8_19 = f8 * (crypto_int64) g8_19; 161 | crypto_int64 f8g9_19 = f8 * (crypto_int64) g9_19; 162 | crypto_int64 f9g0 = f9 * (crypto_int64) g0; 163 | crypto_int64 f9g1_38 = f9_2 * (crypto_int64) g1_19; 164 | crypto_int64 f9g2_19 = f9 * (crypto_int64) g2_19; 165 | crypto_int64 f9g3_38 = f9_2 * (crypto_int64) g3_19; 166 | crypto_int64 f9g4_19 = f9 * (crypto_int64) g4_19; 167 | crypto_int64 f9g5_38 = f9_2 * (crypto_int64) g5_19; 168 | crypto_int64 f9g6_19 = f9 * (crypto_int64) g6_19; 169 | crypto_int64 f9g7_38 = f9_2 * (crypto_int64) g7_19; 170 | crypto_int64 f9g8_19 = f9 * (crypto_int64) g8_19; 171 | crypto_int64 f9g9_38 = f9_2 * (crypto_int64) g9_19; 172 | crypto_int64 h0 = f0g0+f1g9_38+f2g8_19+f3g7_38+f4g6_19+f5g5_38+f6g4_19+f7g3_38+f8g2_19+f9g1_38; 173 | crypto_int64 h1 = f0g1+f1g0 +f2g9_19+f3g8_19+f4g7_19+f5g6_19+f6g5_19+f7g4_19+f8g3_19+f9g2_19; 174 | crypto_int64 h2 = f0g2+f1g1_2 +f2g0 +f3g9_38+f4g8_19+f5g7_38+f6g6_19+f7g5_38+f8g4_19+f9g3_38; 175 | crypto_int64 h3 = f0g3+f1g2 +f2g1 +f3g0 +f4g9_19+f5g8_19+f6g7_19+f7g6_19+f8g5_19+f9g4_19; 176 | crypto_int64 h4 = f0g4+f1g3_2 +f2g2 +f3g1_2 +f4g0 +f5g9_38+f6g8_19+f7g7_38+f8g6_19+f9g5_38; 177 | crypto_int64 h5 = f0g5+f1g4 +f2g3 +f3g2 +f4g1 +f5g0 +f6g9_19+f7g8_19+f8g7_19+f9g6_19; 178 | crypto_int64 h6 = f0g6+f1g5_2 +f2g4 +f3g3_2 +f4g2 +f5g1_2 +f6g0 +f7g9_38+f8g8_19+f9g7_38; 179 | crypto_int64 h7 = f0g7+f1g6 +f2g5 +f3g4 +f4g3 +f5g2 +f6g1 +f7g0 +f8g9_19+f9g8_19; 180 | crypto_int64 h8 = f0g8+f1g7_2 +f2g6 +f3g5_2 +f4g4 +f5g3_2 +f6g2 +f7g1_2 +f8g0 +f9g9_38; 181 | crypto_int64 h9 = f0g9+f1g8 +f2g7 +f3g6 +f4g5 +f5g4 +f6g3 +f7g2 +f8g1 +f9g0 ; 182 | crypto_int64 carry0; 183 | crypto_int64 carry1; 184 | crypto_int64 carry2; 185 | crypto_int64 carry3; 186 | crypto_int64 carry4; 187 | crypto_int64 carry5; 188 | crypto_int64 carry6; 189 | crypto_int64 carry7; 190 | crypto_int64 carry8; 191 | crypto_int64 carry9; 192 | 193 | /* 194 | |h0| <= (1.65*1.65*2^52*(1+19+19+19+19)+1.65*1.65*2^50*(38+38+38+38+38)) 195 | i.e. |h0| <= 1.4*2^60; narrower ranges for h2, h4, h6, h8 196 | |h1| <= (1.65*1.65*2^51*(1+1+19+19+19+19+19+19+19+19)) 197 | i.e. |h1| <= 1.7*2^59; narrower ranges for h3, h5, h7, h9 198 | */ 199 | 200 | carry0 = (h0 + (crypto_int64) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26; 201 | carry4 = (h4 + (crypto_int64) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26; 202 | /* |h0| <= 2^25 */ 203 | /* |h4| <= 2^25 */ 204 | /* |h1| <= 1.71*2^59 */ 205 | /* |h5| <= 1.71*2^59 */ 206 | 207 | carry1 = (h1 + (crypto_int64) (1<<24)) >> 25; h2 += carry1; h1 -= carry1 << 25; 208 | carry5 = (h5 + (crypto_int64) (1<<24)) >> 25; h6 += carry5; h5 -= carry5 << 25; 209 | /* |h1| <= 2^24; from now on fits into int32 */ 210 | /* |h5| <= 2^24; from now on fits into int32 */ 211 | /* |h2| <= 1.41*2^60 */ 212 | /* |h6| <= 1.41*2^60 */ 213 | 214 | carry2 = (h2 + (crypto_int64) (1<<25)) >> 26; h3 += carry2; h2 -= carry2 << 26; 215 | carry6 = (h6 + (crypto_int64) (1<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26; 216 | /* |h2| <= 2^25; from now on fits into int32 unchanged */ 217 | /* |h6| <= 2^25; from now on fits into int32 unchanged */ 218 | /* |h3| <= 1.71*2^59 */ 219 | /* |h7| <= 1.71*2^59 */ 220 | 221 | carry3 = (h3 + (crypto_int64) (1<<24)) >> 25; h4 += carry3; h3 -= carry3 << 25; 222 | carry7 = (h7 + (crypto_int64) (1<<24)) >> 25; h8 += carry7; h7 -= carry7 << 25; 223 | /* |h3| <= 2^24; from now on fits into int32 unchanged */ 224 | /* |h7| <= 2^24; from now on fits into int32 unchanged */ 225 | /* |h4| <= 1.72*2^34 */ 226 | /* |h8| <= 1.41*2^60 */ 227 | 228 | carry4 = (h4 + (crypto_int64) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26; 229 | carry8 = (h8 + (crypto_int64) (1<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26; 230 | /* |h4| <= 2^25; from now on fits into int32 unchanged */ 231 | /* |h8| <= 2^25; from now on fits into int32 unchanged */ 232 | /* |h5| <= 1.01*2^24 */ 233 | /* |h9| <= 1.71*2^59 */ 234 | 235 | carry9 = (h9 + (crypto_int64) (1<<24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25; 236 | /* |h9| <= 2^24; from now on fits into int32 unchanged */ 237 | /* |h0| <= 1.1*2^39 */ 238 | 239 | carry0 = (h0 + (crypto_int64) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26; 240 | /* |h0| <= 2^25; from now on fits into int32 unchanged */ 241 | /* |h1| <= 1.01*2^24 */ 242 | 243 | h[0] = h0; 244 | h[1] = h1; 245 | h[2] = h2; 246 | h[3] = h3; 247 | h[4] = h4; 248 | h[5] = h5; 249 | h[6] = h6; 250 | h[7] = h7; 251 | h[8] = h8; 252 | h[9] = h9; 253 | } 254 | -------------------------------------------------------------------------------- /curve/ed25519/fe_neg.c: -------------------------------------------------------------------------------- 1 | #include "fe.h" 2 | 3 | /* 4 | h = -f 5 | 6 | Preconditions: 7 | |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. 8 | 9 | Postconditions: 10 | |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. 11 | */ 12 | 13 | void fe_neg(fe h,const fe f) 14 | { 15 | crypto_int32 f0 = f[0]; 16 | crypto_int32 f1 = f[1]; 17 | crypto_int32 f2 = f[2]; 18 | crypto_int32 f3 = f[3]; 19 | crypto_int32 f4 = f[4]; 20 | crypto_int32 f5 = f[5]; 21 | crypto_int32 f6 = f[6]; 22 | crypto_int32 f7 = f[7]; 23 | crypto_int32 f8 = f[8]; 24 | crypto_int32 f9 = f[9]; 25 | crypto_int32 h0 = -f0; 26 | crypto_int32 h1 = -f1; 27 | crypto_int32 h2 = -f2; 28 | crypto_int32 h3 = -f3; 29 | crypto_int32 h4 = -f4; 30 | crypto_int32 h5 = -f5; 31 | crypto_int32 h6 = -f6; 32 | crypto_int32 h7 = -f7; 33 | crypto_int32 h8 = -f8; 34 | crypto_int32 h9 = -f9; 35 | h[0] = h0; 36 | h[1] = h1; 37 | h[2] = h2; 38 | h[3] = h3; 39 | h[4] = h4; 40 | h[5] = h5; 41 | h[6] = h6; 42 | h[7] = h7; 43 | h[8] = h8; 44 | h[9] = h9; 45 | } 46 | -------------------------------------------------------------------------------- /curve/ed25519/fe_pow22523.c: -------------------------------------------------------------------------------- 1 | #include "fe.h" 2 | 3 | void fe_pow22523(fe out,const fe z) 4 | { 5 | fe t0; 6 | fe t1; 7 | fe t2; 8 | int i; 9 | 10 | #include "pow22523.h" 11 | 12 | return; 13 | } 14 | -------------------------------------------------------------------------------- /curve/ed25519/fe_sq.c: -------------------------------------------------------------------------------- 1 | #include "fe.h" 2 | #include "crypto_int64.h" 3 | 4 | /* 5 | h = f * f 6 | Can overlap h with f. 7 | 8 | Preconditions: 9 | |f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc. 10 | 11 | Postconditions: 12 | |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc. 13 | */ 14 | 15 | /* 16 | See fe_mul.c for discussion of implementation strategy. 17 | */ 18 | 19 | void fe_sq(fe h,const fe f) 20 | { 21 | crypto_int32 f0 = f[0]; 22 | crypto_int32 f1 = f[1]; 23 | crypto_int32 f2 = f[2]; 24 | crypto_int32 f3 = f[3]; 25 | crypto_int32 f4 = f[4]; 26 | crypto_int32 f5 = f[5]; 27 | crypto_int32 f6 = f[6]; 28 | crypto_int32 f7 = f[7]; 29 | crypto_int32 f8 = f[8]; 30 | crypto_int32 f9 = f[9]; 31 | crypto_int32 f0_2 = 2 * f0; 32 | crypto_int32 f1_2 = 2 * f1; 33 | crypto_int32 f2_2 = 2 * f2; 34 | crypto_int32 f3_2 = 2 * f3; 35 | crypto_int32 f4_2 = 2 * f4; 36 | crypto_int32 f5_2 = 2 * f5; 37 | crypto_int32 f6_2 = 2 * f6; 38 | crypto_int32 f7_2 = 2 * f7; 39 | crypto_int32 f5_38 = 38 * f5; /* 1.959375*2^30 */ 40 | crypto_int32 f6_19 = 19 * f6; /* 1.959375*2^30 */ 41 | crypto_int32 f7_38 = 38 * f7; /* 1.959375*2^30 */ 42 | crypto_int32 f8_19 = 19 * f8; /* 1.959375*2^30 */ 43 | crypto_int32 f9_38 = 38 * f9; /* 1.959375*2^30 */ 44 | crypto_int64 f0f0 = f0 * (crypto_int64) f0; 45 | crypto_int64 f0f1_2 = f0_2 * (crypto_int64) f1; 46 | crypto_int64 f0f2_2 = f0_2 * (crypto_int64) f2; 47 | crypto_int64 f0f3_2 = f0_2 * (crypto_int64) f3; 48 | crypto_int64 f0f4_2 = f0_2 * (crypto_int64) f4; 49 | crypto_int64 f0f5_2 = f0_2 * (crypto_int64) f5; 50 | crypto_int64 f0f6_2 = f0_2 * (crypto_int64) f6; 51 | crypto_int64 f0f7_2 = f0_2 * (crypto_int64) f7; 52 | crypto_int64 f0f8_2 = f0_2 * (crypto_int64) f8; 53 | crypto_int64 f0f9_2 = f0_2 * (crypto_int64) f9; 54 | crypto_int64 f1f1_2 = f1_2 * (crypto_int64) f1; 55 | crypto_int64 f1f2_2 = f1_2 * (crypto_int64) f2; 56 | crypto_int64 f1f3_4 = f1_2 * (crypto_int64) f3_2; 57 | crypto_int64 f1f4_2 = f1_2 * (crypto_int64) f4; 58 | crypto_int64 f1f5_4 = f1_2 * (crypto_int64) f5_2; 59 | crypto_int64 f1f6_2 = f1_2 * (crypto_int64) f6; 60 | crypto_int64 f1f7_4 = f1_2 * (crypto_int64) f7_2; 61 | crypto_int64 f1f8_2 = f1_2 * (crypto_int64) f8; 62 | crypto_int64 f1f9_76 = f1_2 * (crypto_int64) f9_38; 63 | crypto_int64 f2f2 = f2 * (crypto_int64) f2; 64 | crypto_int64 f2f3_2 = f2_2 * (crypto_int64) f3; 65 | crypto_int64 f2f4_2 = f2_2 * (crypto_int64) f4; 66 | crypto_int64 f2f5_2 = f2_2 * (crypto_int64) f5; 67 | crypto_int64 f2f6_2 = f2_2 * (crypto_int64) f6; 68 | crypto_int64 f2f7_2 = f2_2 * (crypto_int64) f7; 69 | crypto_int64 f2f8_38 = f2_2 * (crypto_int64) f8_19; 70 | crypto_int64 f2f9_38 = f2 * (crypto_int64) f9_38; 71 | crypto_int64 f3f3_2 = f3_2 * (crypto_int64) f3; 72 | crypto_int64 f3f4_2 = f3_2 * (crypto_int64) f4; 73 | crypto_int64 f3f5_4 = f3_2 * (crypto_int64) f5_2; 74 | crypto_int64 f3f6_2 = f3_2 * (crypto_int64) f6; 75 | crypto_int64 f3f7_76 = f3_2 * (crypto_int64) f7_38; 76 | crypto_int64 f3f8_38 = f3_2 * (crypto_int64) f8_19; 77 | crypto_int64 f3f9_76 = f3_2 * (crypto_int64) f9_38; 78 | crypto_int64 f4f4 = f4 * (crypto_int64) f4; 79 | crypto_int64 f4f5_2 = f4_2 * (crypto_int64) f5; 80 | crypto_int64 f4f6_38 = f4_2 * (crypto_int64) f6_19; 81 | crypto_int64 f4f7_38 = f4 * (crypto_int64) f7_38; 82 | crypto_int64 f4f8_38 = f4_2 * (crypto_int64) f8_19; 83 | crypto_int64 f4f9_38 = f4 * (crypto_int64) f9_38; 84 | crypto_int64 f5f5_38 = f5 * (crypto_int64) f5_38; 85 | crypto_int64 f5f6_38 = f5_2 * (crypto_int64) f6_19; 86 | crypto_int64 f5f7_76 = f5_2 * (crypto_int64) f7_38; 87 | crypto_int64 f5f8_38 = f5_2 * (crypto_int64) f8_19; 88 | crypto_int64 f5f9_76 = f5_2 * (crypto_int64) f9_38; 89 | crypto_int64 f6f6_19 = f6 * (crypto_int64) f6_19; 90 | crypto_int64 f6f7_38 = f6 * (crypto_int64) f7_38; 91 | crypto_int64 f6f8_38 = f6_2 * (crypto_int64) f8_19; 92 | crypto_int64 f6f9_38 = f6 * (crypto_int64) f9_38; 93 | crypto_int64 f7f7_38 = f7 * (crypto_int64) f7_38; 94 | crypto_int64 f7f8_38 = f7_2 * (crypto_int64) f8_19; 95 | crypto_int64 f7f9_76 = f7_2 * (crypto_int64) f9_38; 96 | crypto_int64 f8f8_19 = f8 * (crypto_int64) f8_19; 97 | crypto_int64 f8f9_38 = f8 * (crypto_int64) f9_38; 98 | crypto_int64 f9f9_38 = f9 * (crypto_int64) f9_38; 99 | crypto_int64 h0 = f0f0 +f1f9_76+f2f8_38+f3f7_76+f4f6_38+f5f5_38; 100 | crypto_int64 h1 = f0f1_2+f2f9_38+f3f8_38+f4f7_38+f5f6_38; 101 | crypto_int64 h2 = f0f2_2+f1f1_2 +f3f9_76+f4f8_38+f5f7_76+f6f6_19; 102 | crypto_int64 h3 = f0f3_2+f1f2_2 +f4f9_38+f5f8_38+f6f7_38; 103 | crypto_int64 h4 = f0f4_2+f1f3_4 +f2f2 +f5f9_76+f6f8_38+f7f7_38; 104 | crypto_int64 h5 = f0f5_2+f1f4_2 +f2f3_2 +f6f9_38+f7f8_38; 105 | crypto_int64 h6 = f0f6_2+f1f5_4 +f2f4_2 +f3f3_2 +f7f9_76+f8f8_19; 106 | crypto_int64 h7 = f0f7_2+f1f6_2 +f2f5_2 +f3f4_2 +f8f9_38; 107 | crypto_int64 h8 = f0f8_2+f1f7_4 +f2f6_2 +f3f5_4 +f4f4 +f9f9_38; 108 | crypto_int64 h9 = f0f9_2+f1f8_2 +f2f7_2 +f3f6_2 +f4f5_2; 109 | crypto_int64 carry0; 110 | crypto_int64 carry1; 111 | crypto_int64 carry2; 112 | crypto_int64 carry3; 113 | crypto_int64 carry4; 114 | crypto_int64 carry5; 115 | crypto_int64 carry6; 116 | crypto_int64 carry7; 117 | crypto_int64 carry8; 118 | crypto_int64 carry9; 119 | 120 | carry0 = (h0 + (crypto_int64) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26; 121 | carry4 = (h4 + (crypto_int64) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26; 122 | 123 | carry1 = (h1 + (crypto_int64) (1<<24)) >> 25; h2 += carry1; h1 -= carry1 << 25; 124 | carry5 = (h5 + (crypto_int64) (1<<24)) >> 25; h6 += carry5; h5 -= carry5 << 25; 125 | 126 | carry2 = (h2 + (crypto_int64) (1<<25)) >> 26; h3 += carry2; h2 -= carry2 << 26; 127 | carry6 = (h6 + (crypto_int64) (1<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26; 128 | 129 | carry3 = (h3 + (crypto_int64) (1<<24)) >> 25; h4 += carry3; h3 -= carry3 << 25; 130 | carry7 = (h7 + (crypto_int64) (1<<24)) >> 25; h8 += carry7; h7 -= carry7 << 25; 131 | 132 | carry4 = (h4 + (crypto_int64) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26; 133 | carry8 = (h8 + (crypto_int64) (1<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26; 134 | 135 | carry9 = (h9 + (crypto_int64) (1<<24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25; 136 | 137 | carry0 = (h0 + (crypto_int64) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26; 138 | 139 | h[0] = h0; 140 | h[1] = h1; 141 | h[2] = h2; 142 | h[3] = h3; 143 | h[4] = h4; 144 | h[5] = h5; 145 | h[6] = h6; 146 | h[7] = h7; 147 | h[8] = h8; 148 | h[9] = h9; 149 | } 150 | -------------------------------------------------------------------------------- /curve/ed25519/fe_sq2.c: -------------------------------------------------------------------------------- 1 | #include "fe.h" 2 | #include "crypto_int64.h" 3 | 4 | /* 5 | h = 2 * f * f 6 | Can overlap h with f. 7 | 8 | Preconditions: 9 | |f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc. 10 | 11 | Postconditions: 12 | |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc. 13 | */ 14 | 15 | /* 16 | See fe_mul.c for discussion of implementation strategy. 17 | */ 18 | 19 | void fe_sq2(fe h,const fe f) 20 | { 21 | crypto_int32 f0 = f[0]; 22 | crypto_int32 f1 = f[1]; 23 | crypto_int32 f2 = f[2]; 24 | crypto_int32 f3 = f[3]; 25 | crypto_int32 f4 = f[4]; 26 | crypto_int32 f5 = f[5]; 27 | crypto_int32 f6 = f[6]; 28 | crypto_int32 f7 = f[7]; 29 | crypto_int32 f8 = f[8]; 30 | crypto_int32 f9 = f[9]; 31 | crypto_int32 f0_2 = 2 * f0; 32 | crypto_int32 f1_2 = 2 * f1; 33 | crypto_int32 f2_2 = 2 * f2; 34 | crypto_int32 f3_2 = 2 * f3; 35 | crypto_int32 f4_2 = 2 * f4; 36 | crypto_int32 f5_2 = 2 * f5; 37 | crypto_int32 f6_2 = 2 * f6; 38 | crypto_int32 f7_2 = 2 * f7; 39 | crypto_int32 f5_38 = 38 * f5; /* 1.959375*2^30 */ 40 | crypto_int32 f6_19 = 19 * f6; /* 1.959375*2^30 */ 41 | crypto_int32 f7_38 = 38 * f7; /* 1.959375*2^30 */ 42 | crypto_int32 f8_19 = 19 * f8; /* 1.959375*2^30 */ 43 | crypto_int32 f9_38 = 38 * f9; /* 1.959375*2^30 */ 44 | crypto_int64 f0f0 = f0 * (crypto_int64) f0; 45 | crypto_int64 f0f1_2 = f0_2 * (crypto_int64) f1; 46 | crypto_int64 f0f2_2 = f0_2 * (crypto_int64) f2; 47 | crypto_int64 f0f3_2 = f0_2 * (crypto_int64) f3; 48 | crypto_int64 f0f4_2 = f0_2 * (crypto_int64) f4; 49 | crypto_int64 f0f5_2 = f0_2 * (crypto_int64) f5; 50 | crypto_int64 f0f6_2 = f0_2 * (crypto_int64) f6; 51 | crypto_int64 f0f7_2 = f0_2 * (crypto_int64) f7; 52 | crypto_int64 f0f8_2 = f0_2 * (crypto_int64) f8; 53 | crypto_int64 f0f9_2 = f0_2 * (crypto_int64) f9; 54 | crypto_int64 f1f1_2 = f1_2 * (crypto_int64) f1; 55 | crypto_int64 f1f2_2 = f1_2 * (crypto_int64) f2; 56 | crypto_int64 f1f3_4 = f1_2 * (crypto_int64) f3_2; 57 | crypto_int64 f1f4_2 = f1_2 * (crypto_int64) f4; 58 | crypto_int64 f1f5_4 = f1_2 * (crypto_int64) f5_2; 59 | crypto_int64 f1f6_2 = f1_2 * (crypto_int64) f6; 60 | crypto_int64 f1f7_4 = f1_2 * (crypto_int64) f7_2; 61 | crypto_int64 f1f8_2 = f1_2 * (crypto_int64) f8; 62 | crypto_int64 f1f9_76 = f1_2 * (crypto_int64) f9_38; 63 | crypto_int64 f2f2 = f2 * (crypto_int64) f2; 64 | crypto_int64 f2f3_2 = f2_2 * (crypto_int64) f3; 65 | crypto_int64 f2f4_2 = f2_2 * (crypto_int64) f4; 66 | crypto_int64 f2f5_2 = f2_2 * (crypto_int64) f5; 67 | crypto_int64 f2f6_2 = f2_2 * (crypto_int64) f6; 68 | crypto_int64 f2f7_2 = f2_2 * (crypto_int64) f7; 69 | crypto_int64 f2f8_38 = f2_2 * (crypto_int64) f8_19; 70 | crypto_int64 f2f9_38 = f2 * (crypto_int64) f9_38; 71 | crypto_int64 f3f3_2 = f3_2 * (crypto_int64) f3; 72 | crypto_int64 f3f4_2 = f3_2 * (crypto_int64) f4; 73 | crypto_int64 f3f5_4 = f3_2 * (crypto_int64) f5_2; 74 | crypto_int64 f3f6_2 = f3_2 * (crypto_int64) f6; 75 | crypto_int64 f3f7_76 = f3_2 * (crypto_int64) f7_38; 76 | crypto_int64 f3f8_38 = f3_2 * (crypto_int64) f8_19; 77 | crypto_int64 f3f9_76 = f3_2 * (crypto_int64) f9_38; 78 | crypto_int64 f4f4 = f4 * (crypto_int64) f4; 79 | crypto_int64 f4f5_2 = f4_2 * (crypto_int64) f5; 80 | crypto_int64 f4f6_38 = f4_2 * (crypto_int64) f6_19; 81 | crypto_int64 f4f7_38 = f4 * (crypto_int64) f7_38; 82 | crypto_int64 f4f8_38 = f4_2 * (crypto_int64) f8_19; 83 | crypto_int64 f4f9_38 = f4 * (crypto_int64) f9_38; 84 | crypto_int64 f5f5_38 = f5 * (crypto_int64) f5_38; 85 | crypto_int64 f5f6_38 = f5_2 * (crypto_int64) f6_19; 86 | crypto_int64 f5f7_76 = f5_2 * (crypto_int64) f7_38; 87 | crypto_int64 f5f8_38 = f5_2 * (crypto_int64) f8_19; 88 | crypto_int64 f5f9_76 = f5_2 * (crypto_int64) f9_38; 89 | crypto_int64 f6f6_19 = f6 * (crypto_int64) f6_19; 90 | crypto_int64 f6f7_38 = f6 * (crypto_int64) f7_38; 91 | crypto_int64 f6f8_38 = f6_2 * (crypto_int64) f8_19; 92 | crypto_int64 f6f9_38 = f6 * (crypto_int64) f9_38; 93 | crypto_int64 f7f7_38 = f7 * (crypto_int64) f7_38; 94 | crypto_int64 f7f8_38 = f7_2 * (crypto_int64) f8_19; 95 | crypto_int64 f7f9_76 = f7_2 * (crypto_int64) f9_38; 96 | crypto_int64 f8f8_19 = f8 * (crypto_int64) f8_19; 97 | crypto_int64 f8f9_38 = f8 * (crypto_int64) f9_38; 98 | crypto_int64 f9f9_38 = f9 * (crypto_int64) f9_38; 99 | crypto_int64 h0 = f0f0 +f1f9_76+f2f8_38+f3f7_76+f4f6_38+f5f5_38; 100 | crypto_int64 h1 = f0f1_2+f2f9_38+f3f8_38+f4f7_38+f5f6_38; 101 | crypto_int64 h2 = f0f2_2+f1f1_2 +f3f9_76+f4f8_38+f5f7_76+f6f6_19; 102 | crypto_int64 h3 = f0f3_2+f1f2_2 +f4f9_38+f5f8_38+f6f7_38; 103 | crypto_int64 h4 = f0f4_2+f1f3_4 +f2f2 +f5f9_76+f6f8_38+f7f7_38; 104 | crypto_int64 h5 = f0f5_2+f1f4_2 +f2f3_2 +f6f9_38+f7f8_38; 105 | crypto_int64 h6 = f0f6_2+f1f5_4 +f2f4_2 +f3f3_2 +f7f9_76+f8f8_19; 106 | crypto_int64 h7 = f0f7_2+f1f6_2 +f2f5_2 +f3f4_2 +f8f9_38; 107 | crypto_int64 h8 = f0f8_2+f1f7_4 +f2f6_2 +f3f5_4 +f4f4 +f9f9_38; 108 | crypto_int64 h9 = f0f9_2+f1f8_2 +f2f7_2 +f3f6_2 +f4f5_2; 109 | crypto_int64 carry0; 110 | crypto_int64 carry1; 111 | crypto_int64 carry2; 112 | crypto_int64 carry3; 113 | crypto_int64 carry4; 114 | crypto_int64 carry5; 115 | crypto_int64 carry6; 116 | crypto_int64 carry7; 117 | crypto_int64 carry8; 118 | crypto_int64 carry9; 119 | 120 | h0 += h0; 121 | h1 += h1; 122 | h2 += h2; 123 | h3 += h3; 124 | h4 += h4; 125 | h5 += h5; 126 | h6 += h6; 127 | h7 += h7; 128 | h8 += h8; 129 | h9 += h9; 130 | 131 | carry0 = (h0 + (crypto_int64) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26; 132 | carry4 = (h4 + (crypto_int64) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26; 133 | 134 | carry1 = (h1 + (crypto_int64) (1<<24)) >> 25; h2 += carry1; h1 -= carry1 << 25; 135 | carry5 = (h5 + (crypto_int64) (1<<24)) >> 25; h6 += carry5; h5 -= carry5 << 25; 136 | 137 | carry2 = (h2 + (crypto_int64) (1<<25)) >> 26; h3 += carry2; h2 -= carry2 << 26; 138 | carry6 = (h6 + (crypto_int64) (1<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26; 139 | 140 | carry3 = (h3 + (crypto_int64) (1<<24)) >> 25; h4 += carry3; h3 -= carry3 << 25; 141 | carry7 = (h7 + (crypto_int64) (1<<24)) >> 25; h8 += carry7; h7 -= carry7 << 25; 142 | 143 | carry4 = (h4 + (crypto_int64) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26; 144 | carry8 = (h8 + (crypto_int64) (1<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26; 145 | 146 | carry9 = (h9 + (crypto_int64) (1<<24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25; 147 | 148 | carry0 = (h0 + (crypto_int64) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26; 149 | 150 | h[0] = h0; 151 | h[1] = h1; 152 | h[2] = h2; 153 | h[3] = h3; 154 | h[4] = h4; 155 | h[5] = h5; 156 | h[6] = h6; 157 | h[7] = h7; 158 | h[8] = h8; 159 | h[9] = h9; 160 | } 161 | -------------------------------------------------------------------------------- /curve/ed25519/fe_sub.c: -------------------------------------------------------------------------------- 1 | #include "fe.h" 2 | 3 | /* 4 | h = f - g 5 | Can overlap h with f or g. 6 | 7 | Preconditions: 8 | |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. 9 | |g| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. 10 | 11 | Postconditions: 12 | |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. 13 | */ 14 | 15 | void fe_sub(fe h,const fe f,const fe g) 16 | { 17 | crypto_int32 f0 = f[0]; 18 | crypto_int32 f1 = f[1]; 19 | crypto_int32 f2 = f[2]; 20 | crypto_int32 f3 = f[3]; 21 | crypto_int32 f4 = f[4]; 22 | crypto_int32 f5 = f[5]; 23 | crypto_int32 f6 = f[6]; 24 | crypto_int32 f7 = f[7]; 25 | crypto_int32 f8 = f[8]; 26 | crypto_int32 f9 = f[9]; 27 | crypto_int32 g0 = g[0]; 28 | crypto_int32 g1 = g[1]; 29 | crypto_int32 g2 = g[2]; 30 | crypto_int32 g3 = g[3]; 31 | crypto_int32 g4 = g[4]; 32 | crypto_int32 g5 = g[5]; 33 | crypto_int32 g6 = g[6]; 34 | crypto_int32 g7 = g[7]; 35 | crypto_int32 g8 = g[8]; 36 | crypto_int32 g9 = g[9]; 37 | crypto_int32 h0 = f0 - g0; 38 | crypto_int32 h1 = f1 - g1; 39 | crypto_int32 h2 = f2 - g2; 40 | crypto_int32 h3 = f3 - g3; 41 | crypto_int32 h4 = f4 - g4; 42 | crypto_int32 h5 = f5 - g5; 43 | crypto_int32 h6 = f6 - g6; 44 | crypto_int32 h7 = f7 - g7; 45 | crypto_int32 h8 = f8 - g8; 46 | crypto_int32 h9 = f9 - g9; 47 | h[0] = h0; 48 | h[1] = h1; 49 | h[2] = h2; 50 | h[3] = h3; 51 | h[4] = h4; 52 | h[5] = h5; 53 | h[6] = h6; 54 | h[7] = h7; 55 | h[8] = h8; 56 | h[9] = h9; 57 | } 58 | -------------------------------------------------------------------------------- /curve/ed25519/fe_tobytes.c: -------------------------------------------------------------------------------- 1 | #include "fe.h" 2 | 3 | /* 4 | Preconditions: 5 | |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. 6 | 7 | Write p=2^255-19; q=floor(h/p). 8 | Basic claim: q = floor(2^(-255)(h + 19 2^(-25)h9 + 2^(-1))). 9 | 10 | Proof: 11 | Have |h|<=p so |q|<=1 so |19^2 2^(-255) q|<1/4. 12 | Also have |h-2^230 h9|<2^231 so |19 2^(-255)(h-2^230 h9)|<1/4. 13 | 14 | Write y=2^(-1)-19^2 2^(-255)q-19 2^(-255)(h-2^230 h9). 15 | Then 0> 25; 53 | q = (h0 + q) >> 26; 54 | q = (h1 + q) >> 25; 55 | q = (h2 + q) >> 26; 56 | q = (h3 + q) >> 25; 57 | q = (h4 + q) >> 26; 58 | q = (h5 + q) >> 25; 59 | q = (h6 + q) >> 26; 60 | q = (h7 + q) >> 25; 61 | q = (h8 + q) >> 26; 62 | q = (h9 + q) >> 25; 63 | 64 | /* Goal: Output h-(2^255-19)q, which is between 0 and 2^255-20. */ 65 | h0 += 19 * q; 66 | /* Goal: Output h-2^255 q, which is between 0 and 2^255-20. */ 67 | 68 | carry0 = h0 >> 26; h1 += carry0; h0 -= carry0 << 26; 69 | carry1 = h1 >> 25; h2 += carry1; h1 -= carry1 << 25; 70 | carry2 = h2 >> 26; h3 += carry2; h2 -= carry2 << 26; 71 | carry3 = h3 >> 25; h4 += carry3; h3 -= carry3 << 25; 72 | carry4 = h4 >> 26; h5 += carry4; h4 -= carry4 << 26; 73 | carry5 = h5 >> 25; h6 += carry5; h5 -= carry5 << 25; 74 | carry6 = h6 >> 26; h7 += carry6; h6 -= carry6 << 26; 75 | carry7 = h7 >> 25; h8 += carry7; h7 -= carry7 << 25; 76 | carry8 = h8 >> 26; h9 += carry8; h8 -= carry8 << 26; 77 | carry9 = h9 >> 25; h9 -= carry9 << 25; 78 | /* h10 = carry9 */ 79 | 80 | /* 81 | Goal: Output h0+...+2^255 h10-2^255 q, which is between 0 and 2^255-20. 82 | Have h0+...+2^230 h9 between 0 and 2^255-1; 83 | evidently 2^255 h10-2^255 q = 0. 84 | Goal: Output h0+...+2^230 h9. 85 | */ 86 | 87 | s[0] = h0 >> 0; 88 | s[1] = h0 >> 8; 89 | s[2] = h0 >> 16; 90 | s[3] = (h0 >> 24) | (h1 << 2); 91 | s[4] = h1 >> 6; 92 | s[5] = h1 >> 14; 93 | s[6] = (h1 >> 22) | (h2 << 3); 94 | s[7] = h2 >> 5; 95 | s[8] = h2 >> 13; 96 | s[9] = (h2 >> 21) | (h3 << 5); 97 | s[10] = h3 >> 3; 98 | s[11] = h3 >> 11; 99 | s[12] = (h3 >> 19) | (h4 << 6); 100 | s[13] = h4 >> 2; 101 | s[14] = h4 >> 10; 102 | s[15] = h4 >> 18; 103 | s[16] = h5 >> 0; 104 | s[17] = h5 >> 8; 105 | s[18] = h5 >> 16; 106 | s[19] = (h5 >> 24) | (h6 << 1); 107 | s[20] = h6 >> 7; 108 | s[21] = h6 >> 15; 109 | s[22] = (h6 >> 23) | (h7 << 3); 110 | s[23] = h7 >> 5; 111 | s[24] = h7 >> 13; 112 | s[25] = (h7 >> 21) | (h8 << 4); 113 | s[26] = h8 >> 4; 114 | s[27] = h8 >> 12; 115 | s[28] = (h8 >> 20) | (h9 << 6); 116 | s[29] = h9 >> 2; 117 | s[30] = h9 >> 10; 118 | s[31] = h9 >> 18; 119 | } 120 | -------------------------------------------------------------------------------- /curve/ed25519/ge.h: -------------------------------------------------------------------------------- 1 | #ifndef GE_H 2 | #define GE_H 3 | 4 | /* 5 | ge means group element. 6 | 7 | Here the group is the set of pairs (x,y) of field elements (see fe.h) 8 | satisfying -x^2 + y^2 = 1 + d x^2y^2 9 | where d = -121665/121666. 10 | 11 | Representations: 12 | ge_p2 (projective): (X:Y:Z) satisfying x=X/Z, y=Y/Z 13 | ge_p3 (extended): (X:Y:Z:T) satisfying x=X/Z, y=Y/Z, XY=ZT 14 | ge_p1p1 (completed): ((X:Z),(Y:T)) satisfying x=X/Z, y=Y/T 15 | ge_precomp (Duif): (y+x,y-x,2dxy) 16 | */ 17 | 18 | #include "fe.h" 19 | 20 | typedef struct { 21 | fe X; 22 | fe Y; 23 | fe Z; 24 | } ge_p2; 25 | 26 | typedef struct { 27 | fe X; 28 | fe Y; 29 | fe Z; 30 | fe T; 31 | } ge_p3; 32 | 33 | typedef struct { 34 | fe X; 35 | fe Y; 36 | fe Z; 37 | fe T; 38 | } ge_p1p1; 39 | 40 | typedef struct { 41 | fe yplusx; 42 | fe yminusx; 43 | fe xy2d; 44 | } ge_precomp; 45 | 46 | typedef struct { 47 | fe YplusX; 48 | fe YminusX; 49 | fe Z; 50 | fe T2d; 51 | } ge_cached; 52 | 53 | #define ge_frombytes_negate_vartime crypto_sign_ed25519_ref10_ge_frombytes_negate_vartime 54 | #define ge_tobytes crypto_sign_ed25519_ref10_ge_tobytes 55 | #define ge_p3_tobytes crypto_sign_ed25519_ref10_ge_p3_tobytes 56 | 57 | #define ge_p2_0 crypto_sign_ed25519_ref10_ge_p2_0 58 | #define ge_p3_0 crypto_sign_ed25519_ref10_ge_p3_0 59 | #define ge_precomp_0 crypto_sign_ed25519_ref10_ge_precomp_0 60 | #define ge_p3_to_p2 crypto_sign_ed25519_ref10_ge_p3_to_p2 61 | #define ge_p3_to_cached crypto_sign_ed25519_ref10_ge_p3_to_cached 62 | #define ge_p1p1_to_p2 crypto_sign_ed25519_ref10_ge_p1p1_to_p2 63 | #define ge_p1p1_to_p3 crypto_sign_ed25519_ref10_ge_p1p1_to_p3 64 | #define ge_p2_dbl crypto_sign_ed25519_ref10_ge_p2_dbl 65 | #define ge_p3_dbl crypto_sign_ed25519_ref10_ge_p3_dbl 66 | 67 | #define ge_madd crypto_sign_ed25519_ref10_ge_madd 68 | #define ge_msub crypto_sign_ed25519_ref10_ge_msub 69 | #define ge_add crypto_sign_ed25519_ref10_ge_add 70 | #define ge_sub crypto_sign_ed25519_ref10_ge_sub 71 | #define ge_scalarmult_base crypto_sign_ed25519_ref10_ge_scalarmult_base 72 | #define ge_double_scalarmult_vartime crypto_sign_ed25519_ref10_ge_double_scalarmult_vartime 73 | 74 | extern void ge_tobytes(unsigned char *,const ge_p2 *); 75 | extern void ge_p3_tobytes(unsigned char *,const ge_p3 *); 76 | extern int ge_frombytes_negate_vartime(ge_p3 *,const unsigned char *); 77 | 78 | extern void ge_p2_0(ge_p2 *); 79 | extern void ge_p3_0(ge_p3 *); 80 | extern void ge_precomp_0(ge_precomp *); 81 | extern void ge_p3_to_p2(ge_p2 *,const ge_p3 *); 82 | extern void ge_p3_to_cached(ge_cached *,const ge_p3 *); 83 | extern void ge_p1p1_to_p2(ge_p2 *,const ge_p1p1 *); 84 | extern void ge_p1p1_to_p3(ge_p3 *,const ge_p1p1 *); 85 | extern void ge_p2_dbl(ge_p1p1 *,const ge_p2 *); 86 | extern void ge_p3_dbl(ge_p1p1 *,const ge_p3 *); 87 | 88 | extern void ge_madd(ge_p1p1 *,const ge_p3 *,const ge_precomp *); 89 | extern void ge_msub(ge_p1p1 *,const ge_p3 *,const ge_precomp *); 90 | extern void ge_add(ge_p1p1 *,const ge_p3 *,const ge_cached *); 91 | extern void ge_sub(ge_p1p1 *,const ge_p3 *,const ge_cached *); 92 | extern void ge_scalarmult_base(ge_p3 *,const unsigned char *); 93 | extern void ge_double_scalarmult_vartime(ge_p2 *,const unsigned char *,const ge_p3 *,const unsigned char *); 94 | 95 | #endif 96 | -------------------------------------------------------------------------------- /curve/ed25519/ge_add.c: -------------------------------------------------------------------------------- 1 | #include "ge.h" 2 | 3 | /* 4 | r = p + q 5 | */ 6 | 7 | void ge_add(ge_p1p1 *r,const ge_p3 *p,const ge_cached *q) 8 | { 9 | fe t0; 10 | #include "ge_add.h" 11 | } 12 | -------------------------------------------------------------------------------- /curve/ed25519/ge_add.h: -------------------------------------------------------------------------------- 1 | 2 | /* qhasm: enter ge_add */ 3 | 4 | /* qhasm: fe X1 */ 5 | 6 | /* qhasm: fe Y1 */ 7 | 8 | /* qhasm: fe Z1 */ 9 | 10 | /* qhasm: fe Z2 */ 11 | 12 | /* qhasm: fe T1 */ 13 | 14 | /* qhasm: fe ZZ */ 15 | 16 | /* qhasm: fe YpX2 */ 17 | 18 | /* qhasm: fe YmX2 */ 19 | 20 | /* qhasm: fe T2d2 */ 21 | 22 | /* qhasm: fe X3 */ 23 | 24 | /* qhasm: fe Y3 */ 25 | 26 | /* qhasm: fe Z3 */ 27 | 28 | /* qhasm: fe T3 */ 29 | 30 | /* qhasm: fe YpX1 */ 31 | 32 | /* qhasm: fe YmX1 */ 33 | 34 | /* qhasm: fe A */ 35 | 36 | /* qhasm: fe B */ 37 | 38 | /* qhasm: fe C */ 39 | 40 | /* qhasm: fe D */ 41 | 42 | /* qhasm: YpX1 = Y1+X1 */ 43 | /* asm 1: fe_add(>YpX1=fe#1,YpX1=r->X,Y,X); */ 45 | fe_add(r->X,p->Y,p->X); 46 | 47 | /* qhasm: YmX1 = Y1-X1 */ 48 | /* asm 1: fe_sub(>YmX1=fe#2,YmX1=r->Y,Y,X); */ 50 | fe_sub(r->Y,p->Y,p->X); 51 | 52 | /* qhasm: A = YpX1*YpX2 */ 53 | /* asm 1: fe_mul(>A=fe#3,A=r->Z,X,YplusX); */ 55 | fe_mul(r->Z,r->X,q->YplusX); 56 | 57 | /* qhasm: B = YmX1*YmX2 */ 58 | /* asm 1: fe_mul(>B=fe#2,B=r->Y,Y,YminusX); */ 60 | fe_mul(r->Y,r->Y,q->YminusX); 61 | 62 | /* qhasm: C = T2d2*T1 */ 63 | /* asm 1: fe_mul(>C=fe#4,C=r->T,T2d,T); */ 65 | fe_mul(r->T,q->T2d,p->T); 66 | 67 | /* qhasm: ZZ = Z1*Z2 */ 68 | /* asm 1: fe_mul(>ZZ=fe#1,ZZ=r->X,Z,Z); */ 70 | fe_mul(r->X,p->Z,q->Z); 71 | 72 | /* qhasm: D = 2*ZZ */ 73 | /* asm 1: fe_add(>D=fe#5,D=t0,X,X); */ 75 | fe_add(t0,r->X,r->X); 76 | 77 | /* qhasm: X3 = A-B */ 78 | /* asm 1: fe_sub(>X3=fe#1,X3=r->X,Z,Y); */ 80 | fe_sub(r->X,r->Z,r->Y); 81 | 82 | /* qhasm: Y3 = A+B */ 83 | /* asm 1: fe_add(>Y3=fe#2,Y3=r->Y,Z,Y); */ 85 | fe_add(r->Y,r->Z,r->Y); 86 | 87 | /* qhasm: Z3 = D+C */ 88 | /* asm 1: fe_add(>Z3=fe#3,Z3=r->Z,T); */ 90 | fe_add(r->Z,t0,r->T); 91 | 92 | /* qhasm: T3 = D-C */ 93 | /* asm 1: fe_sub(>T3=fe#4,T3=r->T,T); */ 95 | fe_sub(r->T,t0,r->T); 96 | 97 | /* qhasm: return */ 98 | -------------------------------------------------------------------------------- /curve/ed25519/ge_double_scalarmult.c: -------------------------------------------------------------------------------- 1 | #include "ge.h" 2 | 3 | static void slide(signed char *r,const unsigned char *a) 4 | { 5 | int i; 6 | int b; 7 | int k; 8 | 9 | for (i = 0;i < 256;++i) 10 | r[i] = 1 & (a[i >> 3] >> (i & 7)); 11 | 12 | for (i = 0;i < 256;++i) 13 | if (r[i]) { 14 | for (b = 1;b <= 6 && i + b < 256;++b) { 15 | if (r[i + b]) { 16 | if (r[i] + (r[i + b] << b) <= 15) { 17 | r[i] += r[i + b] << b; r[i + b] = 0; 18 | } else if (r[i] - (r[i + b] << b) >= -15) { 19 | r[i] -= r[i + b] << b; 20 | for (k = i + b;k < 256;++k) { 21 | if (!r[k]) { 22 | r[k] = 1; 23 | break; 24 | } 25 | r[k] = 0; 26 | } 27 | } else 28 | break; 29 | } 30 | } 31 | } 32 | 33 | } 34 | 35 | static ge_precomp Bi[8] = { 36 | #include "base2.h" 37 | } ; 38 | 39 | /* 40 | r = a * A + b * B 41 | where a = a[0]+256*a[1]+...+256^31 a[31]. 42 | and b = b[0]+256*b[1]+...+256^31 b[31]. 43 | B is the Ed25519 base point (x,4/5) with x positive. 44 | */ 45 | 46 | void ge_double_scalarmult_vartime(ge_p2 *r,const unsigned char *a,const ge_p3 *A,const unsigned char *b) 47 | { 48 | signed char aslide[256]; 49 | signed char bslide[256]; 50 | ge_cached Ai[8]; /* A,3A,5A,7A,9A,11A,13A,15A */ 51 | ge_p1p1 t; 52 | ge_p3 u; 53 | ge_p3 A2; 54 | int i; 55 | 56 | slide(aslide,a); 57 | slide(bslide,b); 58 | 59 | ge_p3_to_cached(&Ai[0],A); 60 | ge_p3_dbl(&t,A); ge_p1p1_to_p3(&A2,&t); 61 | ge_add(&t,&A2,&Ai[0]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[1],&u); 62 | ge_add(&t,&A2,&Ai[1]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[2],&u); 63 | ge_add(&t,&A2,&Ai[2]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[3],&u); 64 | ge_add(&t,&A2,&Ai[3]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[4],&u); 65 | ge_add(&t,&A2,&Ai[4]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[5],&u); 66 | ge_add(&t,&A2,&Ai[5]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[6],&u); 67 | ge_add(&t,&A2,&Ai[6]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[7],&u); 68 | 69 | ge_p2_0(r); 70 | 71 | for (i = 255;i >= 0;--i) { 72 | if (aslide[i] || bslide[i]) break; 73 | } 74 | 75 | for (;i >= 0;--i) { 76 | ge_p2_dbl(&t,r); 77 | 78 | if (aslide[i] > 0) { 79 | ge_p1p1_to_p3(&u,&t); 80 | ge_add(&t,&u,&Ai[aslide[i]/2]); 81 | } else if (aslide[i] < 0) { 82 | ge_p1p1_to_p3(&u,&t); 83 | ge_sub(&t,&u,&Ai[(-aslide[i])/2]); 84 | } 85 | 86 | if (bslide[i] > 0) { 87 | ge_p1p1_to_p3(&u,&t); 88 | ge_madd(&t,&u,&Bi[bslide[i]/2]); 89 | } else if (bslide[i] < 0) { 90 | ge_p1p1_to_p3(&u,&t); 91 | ge_msub(&t,&u,&Bi[(-bslide[i])/2]); 92 | } 93 | 94 | ge_p1p1_to_p2(r,&t); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /curve/ed25519/ge_frombytes.c: -------------------------------------------------------------------------------- 1 | #include "ge.h" 2 | 3 | static const fe d = { 4 | #include "d.h" 5 | } ; 6 | 7 | static const fe sqrtm1 = { 8 | #include "sqrtm1.h" 9 | } ; 10 | 11 | int ge_frombytes_negate_vartime(ge_p3 *h,const unsigned char *s) 12 | { 13 | fe u; 14 | fe v; 15 | fe v3; 16 | fe vxx; 17 | fe check; 18 | 19 | fe_frombytes(h->Y,s); 20 | fe_1(h->Z); 21 | fe_sq(u,h->Y); 22 | fe_mul(v,u,d); 23 | fe_sub(u,u,h->Z); /* u = y^2-1 */ 24 | fe_add(v,v,h->Z); /* v = dy^2+1 */ 25 | 26 | fe_sq(v3,v); 27 | fe_mul(v3,v3,v); /* v3 = v^3 */ 28 | fe_sq(h->X,v3); 29 | fe_mul(h->X,h->X,v); 30 | fe_mul(h->X,h->X,u); /* x = uv^7 */ 31 | 32 | fe_pow22523(h->X,h->X); /* x = (uv^7)^((q-5)/8) */ 33 | fe_mul(h->X,h->X,v3); 34 | fe_mul(h->X,h->X,u); /* x = uv^3(uv^7)^((q-5)/8) */ 35 | 36 | fe_sq(vxx,h->X); 37 | fe_mul(vxx,vxx,v); 38 | fe_sub(check,vxx,u); /* vx^2-u */ 39 | if (fe_isnonzero(check)) { 40 | fe_add(check,vxx,u); /* vx^2+u */ 41 | if (fe_isnonzero(check)) return -1; 42 | fe_mul(h->X,h->X,sqrtm1); 43 | } 44 | 45 | if (fe_isnegative(h->X) == (s[31] >> 7)) 46 | fe_neg(h->X,h->X); 47 | 48 | fe_mul(h->T,h->X,h->Y); 49 | return 0; 50 | } 51 | -------------------------------------------------------------------------------- /curve/ed25519/ge_madd.c: -------------------------------------------------------------------------------- 1 | #include "ge.h" 2 | 3 | /* 4 | r = p + q 5 | */ 6 | 7 | void ge_madd(ge_p1p1 *r,const ge_p3 *p,const ge_precomp *q) 8 | { 9 | fe t0; 10 | #include "ge_madd.h" 11 | } 12 | -------------------------------------------------------------------------------- /curve/ed25519/ge_madd.h: -------------------------------------------------------------------------------- 1 | 2 | /* qhasm: enter ge_madd */ 3 | 4 | /* qhasm: fe X1 */ 5 | 6 | /* qhasm: fe Y1 */ 7 | 8 | /* qhasm: fe Z1 */ 9 | 10 | /* qhasm: fe T1 */ 11 | 12 | /* qhasm: fe ypx2 */ 13 | 14 | /* qhasm: fe ymx2 */ 15 | 16 | /* qhasm: fe xy2d2 */ 17 | 18 | /* qhasm: fe X3 */ 19 | 20 | /* qhasm: fe Y3 */ 21 | 22 | /* qhasm: fe Z3 */ 23 | 24 | /* qhasm: fe T3 */ 25 | 26 | /* qhasm: fe YpX1 */ 27 | 28 | /* qhasm: fe YmX1 */ 29 | 30 | /* qhasm: fe A */ 31 | 32 | /* qhasm: fe B */ 33 | 34 | /* qhasm: fe C */ 35 | 36 | /* qhasm: fe D */ 37 | 38 | /* qhasm: YpX1 = Y1+X1 */ 39 | /* asm 1: fe_add(>YpX1=fe#1,YpX1=r->X,Y,X); */ 41 | fe_add(r->X,p->Y,p->X); 42 | 43 | /* qhasm: YmX1 = Y1-X1 */ 44 | /* asm 1: fe_sub(>YmX1=fe#2,YmX1=r->Y,Y,X); */ 46 | fe_sub(r->Y,p->Y,p->X); 47 | 48 | /* qhasm: A = YpX1*ypx2 */ 49 | /* asm 1: fe_mul(>A=fe#3,A=r->Z,X,yplusx); */ 51 | fe_mul(r->Z,r->X,q->yplusx); 52 | 53 | /* qhasm: B = YmX1*ymx2 */ 54 | /* asm 1: fe_mul(>B=fe#2,B=r->Y,Y,yminusx); */ 56 | fe_mul(r->Y,r->Y,q->yminusx); 57 | 58 | /* qhasm: C = xy2d2*T1 */ 59 | /* asm 1: fe_mul(>C=fe#4,C=r->T,xy2d,T); */ 61 | fe_mul(r->T,q->xy2d,p->T); 62 | 63 | /* qhasm: D = 2*Z1 */ 64 | /* asm 1: fe_add(>D=fe#5,D=t0,Z,Z); */ 66 | fe_add(t0,p->Z,p->Z); 67 | 68 | /* qhasm: X3 = A-B */ 69 | /* asm 1: fe_sub(>X3=fe#1,X3=r->X,Z,Y); */ 71 | fe_sub(r->X,r->Z,r->Y); 72 | 73 | /* qhasm: Y3 = A+B */ 74 | /* asm 1: fe_add(>Y3=fe#2,Y3=r->Y,Z,Y); */ 76 | fe_add(r->Y,r->Z,r->Y); 77 | 78 | /* qhasm: Z3 = D+C */ 79 | /* asm 1: fe_add(>Z3=fe#3,Z3=r->Z,T); */ 81 | fe_add(r->Z,t0,r->T); 82 | 83 | /* qhasm: T3 = D-C */ 84 | /* asm 1: fe_sub(>T3=fe#4,T3=r->T,T); */ 86 | fe_sub(r->T,t0,r->T); 87 | 88 | /* qhasm: return */ 89 | -------------------------------------------------------------------------------- /curve/ed25519/ge_msub.c: -------------------------------------------------------------------------------- 1 | #include "ge.h" 2 | 3 | /* 4 | r = p - q 5 | */ 6 | 7 | void ge_msub(ge_p1p1 *r,const ge_p3 *p,const ge_precomp *q) 8 | { 9 | fe t0; 10 | #include "ge_msub.h" 11 | } 12 | -------------------------------------------------------------------------------- /curve/ed25519/ge_msub.h: -------------------------------------------------------------------------------- 1 | 2 | /* qhasm: enter ge_msub */ 3 | 4 | /* qhasm: fe X1 */ 5 | 6 | /* qhasm: fe Y1 */ 7 | 8 | /* qhasm: fe Z1 */ 9 | 10 | /* qhasm: fe T1 */ 11 | 12 | /* qhasm: fe ypx2 */ 13 | 14 | /* qhasm: fe ymx2 */ 15 | 16 | /* qhasm: fe xy2d2 */ 17 | 18 | /* qhasm: fe X3 */ 19 | 20 | /* qhasm: fe Y3 */ 21 | 22 | /* qhasm: fe Z3 */ 23 | 24 | /* qhasm: fe T3 */ 25 | 26 | /* qhasm: fe YpX1 */ 27 | 28 | /* qhasm: fe YmX1 */ 29 | 30 | /* qhasm: fe A */ 31 | 32 | /* qhasm: fe B */ 33 | 34 | /* qhasm: fe C */ 35 | 36 | /* qhasm: fe D */ 37 | 38 | /* qhasm: YpX1 = Y1+X1 */ 39 | /* asm 1: fe_add(>YpX1=fe#1,YpX1=r->X,Y,X); */ 41 | fe_add(r->X,p->Y,p->X); 42 | 43 | /* qhasm: YmX1 = Y1-X1 */ 44 | /* asm 1: fe_sub(>YmX1=fe#2,YmX1=r->Y,Y,X); */ 46 | fe_sub(r->Y,p->Y,p->X); 47 | 48 | /* qhasm: A = YpX1*ymx2 */ 49 | /* asm 1: fe_mul(>A=fe#3,A=r->Z,X,yminusx); */ 51 | fe_mul(r->Z,r->X,q->yminusx); 52 | 53 | /* qhasm: B = YmX1*ypx2 */ 54 | /* asm 1: fe_mul(>B=fe#2,B=r->Y,Y,yplusx); */ 56 | fe_mul(r->Y,r->Y,q->yplusx); 57 | 58 | /* qhasm: C = xy2d2*T1 */ 59 | /* asm 1: fe_mul(>C=fe#4,C=r->T,xy2d,T); */ 61 | fe_mul(r->T,q->xy2d,p->T); 62 | 63 | /* qhasm: D = 2*Z1 */ 64 | /* asm 1: fe_add(>D=fe#5,D=t0,Z,Z); */ 66 | fe_add(t0,p->Z,p->Z); 67 | 68 | /* qhasm: X3 = A-B */ 69 | /* asm 1: fe_sub(>X3=fe#1,X3=r->X,Z,Y); */ 71 | fe_sub(r->X,r->Z,r->Y); 72 | 73 | /* qhasm: Y3 = A+B */ 74 | /* asm 1: fe_add(>Y3=fe#2,Y3=r->Y,Z,Y); */ 76 | fe_add(r->Y,r->Z,r->Y); 77 | 78 | /* qhasm: Z3 = D-C */ 79 | /* asm 1: fe_sub(>Z3=fe#3,Z3=r->Z,T); */ 81 | fe_sub(r->Z,t0,r->T); 82 | 83 | /* qhasm: T3 = D+C */ 84 | /* asm 1: fe_add(>T3=fe#4,T3=r->T,T); */ 86 | fe_add(r->T,t0,r->T); 87 | 88 | /* qhasm: return */ 89 | -------------------------------------------------------------------------------- /curve/ed25519/ge_p1p1_to_p2.c: -------------------------------------------------------------------------------- 1 | #include "ge.h" 2 | 3 | /* 4 | r = p 5 | */ 6 | 7 | extern void ge_p1p1_to_p2(ge_p2 *r,const ge_p1p1 *p) 8 | { 9 | fe_mul(r->X,p->X,p->T); 10 | fe_mul(r->Y,p->Y,p->Z); 11 | fe_mul(r->Z,p->Z,p->T); 12 | } 13 | -------------------------------------------------------------------------------- /curve/ed25519/ge_p1p1_to_p3.c: -------------------------------------------------------------------------------- 1 | #include "ge.h" 2 | 3 | /* 4 | r = p 5 | */ 6 | 7 | extern void ge_p1p1_to_p3(ge_p3 *r,const ge_p1p1 *p) 8 | { 9 | fe_mul(r->X,p->X,p->T); 10 | fe_mul(r->Y,p->Y,p->Z); 11 | fe_mul(r->Z,p->Z,p->T); 12 | fe_mul(r->T,p->X,p->Y); 13 | } 14 | -------------------------------------------------------------------------------- /curve/ed25519/ge_p2_0.c: -------------------------------------------------------------------------------- 1 | #include "ge.h" 2 | 3 | void ge_p2_0(ge_p2 *h) 4 | { 5 | fe_0(h->X); 6 | fe_1(h->Y); 7 | fe_1(h->Z); 8 | } 9 | -------------------------------------------------------------------------------- /curve/ed25519/ge_p2_dbl.c: -------------------------------------------------------------------------------- 1 | #include "ge.h" 2 | 3 | /* 4 | r = 2 * p 5 | */ 6 | 7 | void ge_p2_dbl(ge_p1p1 *r,const ge_p2 *p) 8 | { 9 | fe t0; 10 | #include "ge_p2_dbl.h" 11 | } 12 | -------------------------------------------------------------------------------- /curve/ed25519/ge_p2_dbl.h: -------------------------------------------------------------------------------- 1 | 2 | /* qhasm: enter ge_p2_dbl */ 3 | 4 | /* qhasm: fe X1 */ 5 | 6 | /* qhasm: fe Y1 */ 7 | 8 | /* qhasm: fe Z1 */ 9 | 10 | /* qhasm: fe A */ 11 | 12 | /* qhasm: fe AA */ 13 | 14 | /* qhasm: fe XX */ 15 | 16 | /* qhasm: fe YY */ 17 | 18 | /* qhasm: fe B */ 19 | 20 | /* qhasm: fe X3 */ 21 | 22 | /* qhasm: fe Y3 */ 23 | 24 | /* qhasm: fe Z3 */ 25 | 26 | /* qhasm: fe T3 */ 27 | 28 | /* qhasm: XX=X1^2 */ 29 | /* asm 1: fe_sq(>XX=fe#1,XX=r->X,X); */ 31 | fe_sq(r->X,p->X); 32 | 33 | /* qhasm: YY=Y1^2 */ 34 | /* asm 1: fe_sq(>YY=fe#3,YY=r->Z,Y); */ 36 | fe_sq(r->Z,p->Y); 37 | 38 | /* qhasm: B=2*Z1^2 */ 39 | /* asm 1: fe_sq2(>B=fe#4,B=r->T,Z); */ 41 | fe_sq2(r->T,p->Z); 42 | 43 | /* qhasm: A=X1+Y1 */ 44 | /* asm 1: fe_add(>A=fe#2,A=r->Y,X,Y); */ 46 | fe_add(r->Y,p->X,p->Y); 47 | 48 | /* qhasm: AA=A^2 */ 49 | /* asm 1: fe_sq(>AA=fe#5,AA=t0,Y); */ 51 | fe_sq(t0,r->Y); 52 | 53 | /* qhasm: Y3=YY+XX */ 54 | /* asm 1: fe_add(>Y3=fe#2,Y3=r->Y,Z,X); */ 56 | fe_add(r->Y,r->Z,r->X); 57 | 58 | /* qhasm: Z3=YY-XX */ 59 | /* asm 1: fe_sub(>Z3=fe#3,Z3=r->Z,Z,X); */ 61 | fe_sub(r->Z,r->Z,r->X); 62 | 63 | /* qhasm: X3=AA-Y3 */ 64 | /* asm 1: fe_sub(>X3=fe#1,X3=r->X,Y); */ 66 | fe_sub(r->X,t0,r->Y); 67 | 68 | /* qhasm: T3=B-Z3 */ 69 | /* asm 1: fe_sub(>T3=fe#4,T3=r->T,T,Z); */ 71 | fe_sub(r->T,r->T,r->Z); 72 | 73 | /* qhasm: return */ 74 | -------------------------------------------------------------------------------- /curve/ed25519/ge_p3_0.c: -------------------------------------------------------------------------------- 1 | #include "ge.h" 2 | 3 | void ge_p3_0(ge_p3 *h) 4 | { 5 | fe_0(h->X); 6 | fe_1(h->Y); 7 | fe_1(h->Z); 8 | fe_0(h->T); 9 | } 10 | -------------------------------------------------------------------------------- /curve/ed25519/ge_p3_dbl.c: -------------------------------------------------------------------------------- 1 | #include "ge.h" 2 | 3 | /* 4 | r = 2 * p 5 | */ 6 | 7 | void ge_p3_dbl(ge_p1p1 *r,const ge_p3 *p) 8 | { 9 | ge_p2 q; 10 | ge_p3_to_p2(&q,p); 11 | ge_p2_dbl(r,&q); 12 | } 13 | -------------------------------------------------------------------------------- /curve/ed25519/ge_p3_to_cached.c: -------------------------------------------------------------------------------- 1 | #include "ge.h" 2 | 3 | /* 4 | r = p 5 | */ 6 | 7 | static const fe d2 = { 8 | #include "d2.h" 9 | } ; 10 | 11 | extern void ge_p3_to_cached(ge_cached *r,const ge_p3 *p) 12 | { 13 | fe_add(r->YplusX,p->Y,p->X); 14 | fe_sub(r->YminusX,p->Y,p->X); 15 | fe_copy(r->Z,p->Z); 16 | fe_mul(r->T2d,p->T,d2); 17 | } 18 | -------------------------------------------------------------------------------- /curve/ed25519/ge_p3_to_p2.c: -------------------------------------------------------------------------------- 1 | #include "ge.h" 2 | 3 | /* 4 | r = p 5 | */ 6 | 7 | extern void ge_p3_to_p2(ge_p2 *r,const ge_p3 *p) 8 | { 9 | fe_copy(r->X,p->X); 10 | fe_copy(r->Y,p->Y); 11 | fe_copy(r->Z,p->Z); 12 | } 13 | -------------------------------------------------------------------------------- /curve/ed25519/ge_p3_tobytes.c: -------------------------------------------------------------------------------- 1 | #include "ge.h" 2 | 3 | void ge_p3_tobytes(unsigned char *s,const ge_p3 *h) 4 | { 5 | fe recip; 6 | fe x; 7 | fe y; 8 | 9 | fe_invert(recip,h->Z); 10 | fe_mul(x,h->X,recip); 11 | fe_mul(y,h->Y,recip); 12 | fe_tobytes(s,y); 13 | s[31] ^= fe_isnegative(x) << 7; 14 | } 15 | -------------------------------------------------------------------------------- /curve/ed25519/ge_precomp_0.c: -------------------------------------------------------------------------------- 1 | #include "ge.h" 2 | 3 | void ge_precomp_0(ge_precomp *h) 4 | { 5 | fe_1(h->yplusx); 6 | fe_1(h->yminusx); 7 | fe_0(h->xy2d); 8 | } 9 | -------------------------------------------------------------------------------- /curve/ed25519/ge_scalarmult_base.c: -------------------------------------------------------------------------------- 1 | #include "ge.h" 2 | #include "crypto_uint32.h" 3 | 4 | static unsigned char equal(signed char b,signed char c) 5 | { 6 | unsigned char ub = b; 7 | unsigned char uc = c; 8 | unsigned char x = ub ^ uc; /* 0: yes; 1..255: no */ 9 | crypto_uint32 y = x; /* 0: yes; 1..255: no */ 10 | y -= 1; /* 4294967295: yes; 0..254: no */ 11 | y >>= 31; /* 1: yes; 0: no */ 12 | return y; 13 | } 14 | 15 | static unsigned char negative(signed char b) 16 | { 17 | unsigned long long x = b; /* 18446744073709551361..18446744073709551615: yes; 0..255: no */ 18 | x >>= 63; /* 1: yes; 0: no */ 19 | return x; 20 | } 21 | 22 | static void cmov(ge_precomp *t,ge_precomp *u,unsigned char b) 23 | { 24 | fe_cmov(t->yplusx,u->yplusx,b); 25 | fe_cmov(t->yminusx,u->yminusx,b); 26 | fe_cmov(t->xy2d,u->xy2d,b); 27 | } 28 | 29 | /* base[i][j] = (j+1)*256^i*B */ 30 | static ge_precomp base[32][8] = { 31 | #include "base.h" 32 | } ; 33 | 34 | static void select(ge_precomp *t,int pos,signed char b) 35 | { 36 | ge_precomp minust; 37 | unsigned char bnegative = negative(b); 38 | unsigned char babs = b - (((-bnegative) & b) << 1); 39 | 40 | ge_precomp_0(t); 41 | cmov(t,&base[pos][0],equal(babs,1)); 42 | cmov(t,&base[pos][1],equal(babs,2)); 43 | cmov(t,&base[pos][2],equal(babs,3)); 44 | cmov(t,&base[pos][3],equal(babs,4)); 45 | cmov(t,&base[pos][4],equal(babs,5)); 46 | cmov(t,&base[pos][5],equal(babs,6)); 47 | cmov(t,&base[pos][6],equal(babs,7)); 48 | cmov(t,&base[pos][7],equal(babs,8)); 49 | fe_copy(minust.yplusx,t->yminusx); 50 | fe_copy(minust.yminusx,t->yplusx); 51 | fe_neg(minust.xy2d,t->xy2d); 52 | cmov(t,&minust,bnegative); 53 | } 54 | 55 | /* 56 | h = a * B 57 | where a = a[0]+256*a[1]+...+256^31 a[31] 58 | B is the Ed25519 base point (x,4/5) with x positive. 59 | 60 | Preconditions: 61 | a[31] <= 127 62 | */ 63 | 64 | void ge_scalarmult_base(ge_p3 *h,const unsigned char *a) 65 | { 66 | signed char e[64]; 67 | signed char carry; 68 | ge_p1p1 r; 69 | ge_p2 s; 70 | ge_precomp t; 71 | int i; 72 | 73 | for (i = 0;i < 32;++i) { 74 | e[2 * i + 0] = (a[i] >> 0) & 15; 75 | e[2 * i + 1] = (a[i] >> 4) & 15; 76 | } 77 | /* each e[i] is between 0 and 15 */ 78 | /* e[63] is between 0 and 7 */ 79 | 80 | carry = 0; 81 | for (i = 0;i < 63;++i) { 82 | e[i] += carry; 83 | carry = e[i] + 8; 84 | carry >>= 4; 85 | e[i] -= carry << 4; 86 | } 87 | e[63] += carry; 88 | /* each e[i] is between -8 and 8 */ 89 | 90 | ge_p3_0(h); 91 | for (i = 1;i < 64;i += 2) { 92 | select(&t,i / 2,e[i]); 93 | ge_madd(&r,h,&t); ge_p1p1_to_p3(h,&r); 94 | } 95 | 96 | ge_p3_dbl(&r,h); ge_p1p1_to_p2(&s,&r); 97 | ge_p2_dbl(&r,&s); ge_p1p1_to_p2(&s,&r); 98 | ge_p2_dbl(&r,&s); ge_p1p1_to_p2(&s,&r); 99 | ge_p2_dbl(&r,&s); ge_p1p1_to_p3(h,&r); 100 | 101 | for (i = 0;i < 64;i += 2) { 102 | select(&t,i / 2,e[i]); 103 | ge_madd(&r,h,&t); ge_p1p1_to_p3(h,&r); 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /curve/ed25519/ge_sub.c: -------------------------------------------------------------------------------- 1 | #include "ge.h" 2 | 3 | /* 4 | r = p - q 5 | */ 6 | 7 | void ge_sub(ge_p1p1 *r,const ge_p3 *p,const ge_cached *q) 8 | { 9 | fe t0; 10 | #include "ge_sub.h" 11 | } 12 | -------------------------------------------------------------------------------- /curve/ed25519/ge_sub.h: -------------------------------------------------------------------------------- 1 | 2 | /* qhasm: enter ge_sub */ 3 | 4 | /* qhasm: fe X1 */ 5 | 6 | /* qhasm: fe Y1 */ 7 | 8 | /* qhasm: fe Z1 */ 9 | 10 | /* qhasm: fe Z2 */ 11 | 12 | /* qhasm: fe T1 */ 13 | 14 | /* qhasm: fe ZZ */ 15 | 16 | /* qhasm: fe YpX2 */ 17 | 18 | /* qhasm: fe YmX2 */ 19 | 20 | /* qhasm: fe T2d2 */ 21 | 22 | /* qhasm: fe X3 */ 23 | 24 | /* qhasm: fe Y3 */ 25 | 26 | /* qhasm: fe Z3 */ 27 | 28 | /* qhasm: fe T3 */ 29 | 30 | /* qhasm: fe YpX1 */ 31 | 32 | /* qhasm: fe YmX1 */ 33 | 34 | /* qhasm: fe A */ 35 | 36 | /* qhasm: fe B */ 37 | 38 | /* qhasm: fe C */ 39 | 40 | /* qhasm: fe D */ 41 | 42 | /* qhasm: YpX1 = Y1+X1 */ 43 | /* asm 1: fe_add(>YpX1=fe#1,YpX1=r->X,Y,X); */ 45 | fe_add(r->X,p->Y,p->X); 46 | 47 | /* qhasm: YmX1 = Y1-X1 */ 48 | /* asm 1: fe_sub(>YmX1=fe#2,YmX1=r->Y,Y,X); */ 50 | fe_sub(r->Y,p->Y,p->X); 51 | 52 | /* qhasm: A = YpX1*YmX2 */ 53 | /* asm 1: fe_mul(>A=fe#3,A=r->Z,X,YminusX); */ 55 | fe_mul(r->Z,r->X,q->YminusX); 56 | 57 | /* qhasm: B = YmX1*YpX2 */ 58 | /* asm 1: fe_mul(>B=fe#2,B=r->Y,Y,YplusX); */ 60 | fe_mul(r->Y,r->Y,q->YplusX); 61 | 62 | /* qhasm: C = T2d2*T1 */ 63 | /* asm 1: fe_mul(>C=fe#4,C=r->T,T2d,T); */ 65 | fe_mul(r->T,q->T2d,p->T); 66 | 67 | /* qhasm: ZZ = Z1*Z2 */ 68 | /* asm 1: fe_mul(>ZZ=fe#1,ZZ=r->X,Z,Z); */ 70 | fe_mul(r->X,p->Z,q->Z); 71 | 72 | /* qhasm: D = 2*ZZ */ 73 | /* asm 1: fe_add(>D=fe#5,D=t0,X,X); */ 75 | fe_add(t0,r->X,r->X); 76 | 77 | /* qhasm: X3 = A-B */ 78 | /* asm 1: fe_sub(>X3=fe#1,X3=r->X,Z,Y); */ 80 | fe_sub(r->X,r->Z,r->Y); 81 | 82 | /* qhasm: Y3 = A+B */ 83 | /* asm 1: fe_add(>Y3=fe#2,Y3=r->Y,Z,Y); */ 85 | fe_add(r->Y,r->Z,r->Y); 86 | 87 | /* qhasm: Z3 = D-C */ 88 | /* asm 1: fe_sub(>Z3=fe#3,Z3=r->Z,T); */ 90 | fe_sub(r->Z,t0,r->T); 91 | 92 | /* qhasm: T3 = D+C */ 93 | /* asm 1: fe_add(>T3=fe#4,T3=r->T,T); */ 95 | fe_add(r->T,t0,r->T); 96 | 97 | /* qhasm: return */ 98 | -------------------------------------------------------------------------------- /curve/ed25519/ge_tobytes.c: -------------------------------------------------------------------------------- 1 | #include "ge.h" 2 | 3 | void ge_tobytes(unsigned char *s,const ge_p2 *h) 4 | { 5 | fe recip; 6 | fe x; 7 | fe y; 8 | 9 | fe_invert(recip,h->Z); 10 | fe_mul(x,h->X,recip); 11 | fe_mul(y,h->Y,recip); 12 | fe_tobytes(s,y); 13 | s[31] ^= fe_isnegative(x) << 7; 14 | } 15 | -------------------------------------------------------------------------------- /curve/ed25519/main/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "crypto_hash_sha512.h" 4 | #include "curve_sigs.h" 5 | 6 | #define MSG_LEN 200 7 | 8 | int main(int argc, char* argv[]) 9 | { 10 | unsigned char privkey[32]; 11 | unsigned char pubkey[32]; 12 | unsigned char signature[64]; 13 | unsigned char msg[MSG_LEN]; 14 | unsigned char random[64]; 15 | 16 | /* Initialize pubkey, privkey, msg */ 17 | memset(msg, 0, MSG_LEN); 18 | memset(privkey, 0, 32); 19 | memset(pubkey, 0, 32); 20 | privkey[0] &= 248; 21 | privkey[31] &= 63; 22 | privkey[31] |= 64; 23 | 24 | privkey[8] = 189; /* just so there's some bits set */ 25 | 26 | 27 | /* SHA512 test */ 28 | unsigned char sha512_input[112] = "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"; 29 | unsigned char sha512_correct_output[64] = 30 | { 31 | 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA, 32 | 0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F, 33 | 0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1, 34 | 0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18, 35 | 0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4, 36 | 0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A, 37 | 0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54, 38 | 0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 39 | }; 40 | unsigned char sha512_actual_output[64]; 41 | 42 | crypto_hash_sha512(sha512_actual_output, sha512_input, sizeof(sha512_input)); 43 | if (memcmp(sha512_actual_output, sha512_correct_output, 64) != 0) 44 | printf("SHA512 bad #1\n"); 45 | else 46 | printf("SHA512 good #1\n"); 47 | 48 | sha512_input[111] ^= 1; 49 | 50 | crypto_hash_sha512(sha512_actual_output, sha512_input, sizeof(sha512_input)); 51 | if (memcmp(sha512_actual_output, sha512_correct_output, 64) != 0) 52 | printf("SHA512 good #2\n"); 53 | else 54 | printf("SHA512 bad #2\n"); 55 | 56 | /* Signature test */ 57 | curve25519_keygen(pubkey, privkey); 58 | 59 | curve25519_sign(signature, privkey, msg, MSG_LEN, random); 60 | 61 | if (curve25519_verify(signature, pubkey, msg, MSG_LEN) == 0) 62 | printf("Signature good #1\n"); 63 | else 64 | printf("Signature bad #1\n"); 65 | 66 | signature[0] ^= 1; 67 | 68 | if (curve25519_verify(signature, pubkey, msg, MSG_LEN) == 0) 69 | printf("Signature bad #2\n"); 70 | else 71 | printf("Signature good #2\n"); 72 | 73 | 74 | printf("Random testing...\n"); 75 | for (int count = 0; count < 10000; count++) { 76 | unsigned char b[64]; 77 | crypto_hash_sha512(b, privkey, 32); 78 | memmove(privkey, b, 32); 79 | crypto_hash_sha512(b, privkey, 32); 80 | memmove(random, b, 64); 81 | 82 | privkey[0] &= 248; 83 | privkey[31] &= 63; 84 | privkey[31] |= 64; 85 | 86 | curve25519_keygen(pubkey, privkey); 87 | 88 | curve25519_sign(signature, privkey, msg, MSG_LEN, random); 89 | 90 | if (curve25519_verify(signature, pubkey, msg, MSG_LEN) != 0) { 91 | printf("failure #1 %d\n", count); 92 | return -1; 93 | } 94 | 95 | if (b[63] & 1) 96 | signature[count % 64] ^= 1; 97 | else 98 | msg[count % MSG_LEN] ^= 1; 99 | if (curve25519_verify(signature, pubkey, msg, MSG_LEN) == 0) { 100 | printf("failure #2 %d\n", count); 101 | return -1; 102 | } 103 | } 104 | printf("OK\n"); 105 | return 1; 106 | } 107 | -------------------------------------------------------------------------------- /curve/ed25519/nacl_includes/crypto_int32.h: -------------------------------------------------------------------------------- 1 | #ifndef crypto_int32_h 2 | #define crypto_int32_h 3 | 4 | typedef int crypto_int32; 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /curve/ed25519/nacl_includes/crypto_int64.h: -------------------------------------------------------------------------------- 1 | #ifndef crypto_int64_h 2 | #define crypto_int64_h 3 | 4 | typedef long long crypto_int64; 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /curve/ed25519/nacl_includes/crypto_sign.h: -------------------------------------------------------------------------------- 1 | #ifndef crypto_sign_H 2 | #define crypto_sign_H 3 | 4 | #include "crypto_sign_edwards25519sha512batch.h" 5 | 6 | #define crypto_sign crypto_sign_edwards25519sha512batch 7 | #define crypto_sign_open crypto_sign_edwards25519sha512batch_open 8 | #define crypto_sign_keypair crypto_sign_edwards25519sha512batch_keypair 9 | #define crypto_sign_BYTES crypto_sign_edwards25519sha512batch_BYTES 10 | #define crypto_sign_PUBLICKEYBYTES crypto_sign_edwards25519sha512batch_PUBLICKEYBYTES 11 | #define crypto_sign_SECRETKEYBYTES crypto_sign_edwards25519sha512batch_SECRETKEYBYTES 12 | #define crypto_sign_PRIMITIVE "edwards25519sha512batch" 13 | #define crypto_sign_IMPLEMENTATION crypto_sign_edwards25519sha512batch_IMPLEMENTATION 14 | #define crypto_sign_VERSION crypto_sign_edwards25519sha512batch_VERSION 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /curve/ed25519/nacl_includes/crypto_sign_edwards25519sha512batch.h: -------------------------------------------------------------------------------- 1 | #ifndef crypto_sign_edwards25519sha512batch_H 2 | #define crypto_sign_edwards25519sha512batch_H 3 | 4 | #define crypto_sign_edwards25519sha512batch_ref10_SECRETKEYBYTES 64 5 | #define crypto_sign_edwards25519sha512batch_ref10_PUBLICKEYBYTES 32 6 | #define crypto_sign_edwards25519sha512batch_ref10_BYTES 64 7 | #ifdef __cplusplus 8 | #include 9 | extern std::string crypto_sign_edwards25519sha512batch_ref10(const std::string &,const std::string &); 10 | extern std::string crypto_sign_edwards25519sha512batch_ref10_open(const std::string &,const std::string &); 11 | extern std::string crypto_sign_edwards25519sha512batch_ref10_keypair(std::string *); 12 | extern "C" { 13 | #endif 14 | extern int crypto_sign_edwards25519sha512batch_ref10(unsigned char *,unsigned long long *,const unsigned char *,unsigned long long,const unsigned char *); 15 | extern int crypto_sign_edwards25519sha512batch_ref10_open(unsigned char *,unsigned long long *,const unsigned char *,unsigned long long,const unsigned char *); 16 | extern int crypto_sign_edwards25519sha512batch_ref10_keypair(unsigned char *,unsigned char *); 17 | #ifdef __cplusplus 18 | } 19 | #endif 20 | 21 | #define crypto_sign_edwards25519sha512batch crypto_sign_edwards25519sha512batch_ref10 22 | #define crypto_sign_edwards25519sha512batch_open crypto_sign_edwards25519sha512batch_ref10_open 23 | #define crypto_sign_edwards25519sha512batch_keypair crypto_sign_edwards25519sha512batch_ref10_keypair 24 | #define crypto_sign_edwards25519sha512batch_BYTES crypto_sign_edwards25519sha512batch_ref10_BYTES 25 | #define crypto_sign_edwards25519sha512batch_PUBLICKEYBYTES crypto_sign_edwards25519sha512batch_ref10_PUBLICKEYBYTES 26 | #define crypto_sign_edwards25519sha512batch_SECRETKEYBYTES crypto_sign_edwards25519sha512batch_ref10_SECRETKEYBYTES 27 | #define crypto_sign_edwards25519sha512batch_IMPLEMENTATION "crypto_sign/edwards25519sha512batch/ref10" 28 | #ifndef crypto_sign_edwards25519sha512batch_ref10_VERSION 29 | #define crypto_sign_edwards25519sha512batch_ref10_VERSION "-" 30 | #endif 31 | #define crypto_sign_edwards25519sha512batch_VERSION crypto_sign_edwards25519sha512batch_ref10_VERSION 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /curve/ed25519/nacl_includes/crypto_uint32.h: -------------------------------------------------------------------------------- 1 | #ifndef crypto_uint32_h 2 | #define crypto_uint32_h 3 | 4 | typedef unsigned int crypto_uint32; 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /curve/ed25519/nacl_includes/crypto_uint64.h: -------------------------------------------------------------------------------- 1 | #ifndef crypto_uint64_h 2 | #define crypto_uint64_h 3 | 4 | typedef unsigned long long crypto_uint64; 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /curve/ed25519/nacl_includes/crypto_verify_32.h: -------------------------------------------------------------------------------- 1 | #ifndef crypto_verify_32_H 2 | #define crypto_verify_32_H 3 | 4 | #define crypto_verify_32_ref_BYTES 32 5 | #ifdef __cplusplus 6 | #include 7 | extern "C" { 8 | #endif 9 | extern int crypto_verify_32_ref(const unsigned char *,const unsigned char *); 10 | #ifdef __cplusplus 11 | } 12 | #endif 13 | 14 | #define crypto_verify_32 crypto_verify_32_ref 15 | #define crypto_verify_32_BYTES crypto_verify_32_ref_BYTES 16 | #define crypto_verify_32_IMPLEMENTATION "crypto_verify/32/ref" 17 | #ifndef crypto_verify_32_ref_VERSION 18 | #define crypto_verify_32_ref_VERSION "-" 19 | #endif 20 | #define crypto_verify_32_VERSION crypto_verify_32_ref_VERSION 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /curve/ed25519/nacl_sha512/blocks.c: -------------------------------------------------------------------------------- 1 | #include 2 | typedef uint64_t uint64; 3 | 4 | static uint64 load_bigendian(const unsigned char *x) 5 | { 6 | return 7 | (uint64) (x[7]) \ 8 | | (((uint64) (x[6])) << 8) \ 9 | | (((uint64) (x[5])) << 16) \ 10 | | (((uint64) (x[4])) << 24) \ 11 | | (((uint64) (x[3])) << 32) \ 12 | | (((uint64) (x[2])) << 40) \ 13 | | (((uint64) (x[1])) << 48) \ 14 | | (((uint64) (x[0])) << 56) 15 | ; 16 | } 17 | 18 | static void store_bigendian(unsigned char *x,uint64 u) 19 | { 20 | x[7] = u; u >>= 8; 21 | x[6] = u; u >>= 8; 22 | x[5] = u; u >>= 8; 23 | x[4] = u; u >>= 8; 24 | x[3] = u; u >>= 8; 25 | x[2] = u; u >>= 8; 26 | x[1] = u; u >>= 8; 27 | x[0] = u; 28 | } 29 | 30 | #define SHR(x,c) ((x) >> (c)) 31 | #define ROTR(x,c) (((x) >> (c)) | ((x) << (64 - (c)))) 32 | 33 | #define Ch(x,y,z) ((x & y) ^ (~x & z)) 34 | #define Maj(x,y,z) ((x & y) ^ (x & z) ^ (y & z)) 35 | #define Sigma0(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39)) 36 | #define Sigma1(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41)) 37 | #define sigma0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x,7)) 38 | #define sigma1(x) (ROTR(x,19) ^ ROTR(x,61) ^ SHR(x,6)) 39 | 40 | #define M(w0,w14,w9,w1) w0 = sigma1(w14) + w9 + sigma0(w1) + w0; 41 | 42 | #define EXPAND \ 43 | M(w0 ,w14,w9 ,w1 ) \ 44 | M(w1 ,w15,w10,w2 ) \ 45 | M(w2 ,w0 ,w11,w3 ) \ 46 | M(w3 ,w1 ,w12,w4 ) \ 47 | M(w4 ,w2 ,w13,w5 ) \ 48 | M(w5 ,w3 ,w14,w6 ) \ 49 | M(w6 ,w4 ,w15,w7 ) \ 50 | M(w7 ,w5 ,w0 ,w8 ) \ 51 | M(w8 ,w6 ,w1 ,w9 ) \ 52 | M(w9 ,w7 ,w2 ,w10) \ 53 | M(w10,w8 ,w3 ,w11) \ 54 | M(w11,w9 ,w4 ,w12) \ 55 | M(w12,w10,w5 ,w13) \ 56 | M(w13,w11,w6 ,w14) \ 57 | M(w14,w12,w7 ,w15) \ 58 | M(w15,w13,w8 ,w0 ) 59 | 60 | #define F(w,k) \ 61 | T1 = h + Sigma1(e) + Ch(e,f,g) + k + w; \ 62 | T2 = Sigma0(a) + Maj(a,b,c); \ 63 | h = g; \ 64 | g = f; \ 65 | f = e; \ 66 | e = d + T1; \ 67 | d = c; \ 68 | c = b; \ 69 | b = a; \ 70 | a = T1 + T2; 71 | 72 | int crypto_hashblocks_sha512(unsigned char *statebytes,const unsigned char *in,unsigned long long inlen) 73 | { 74 | uint64 state[8]; 75 | uint64 a; 76 | uint64 b; 77 | uint64 c; 78 | uint64 d; 79 | uint64 e; 80 | uint64 f; 81 | uint64 g; 82 | uint64 h; 83 | uint64 T1; 84 | uint64 T2; 85 | 86 | a = load_bigendian(statebytes + 0); state[0] = a; 87 | b = load_bigendian(statebytes + 8); state[1] = b; 88 | c = load_bigendian(statebytes + 16); state[2] = c; 89 | d = load_bigendian(statebytes + 24); state[3] = d; 90 | e = load_bigendian(statebytes + 32); state[4] = e; 91 | f = load_bigendian(statebytes + 40); state[5] = f; 92 | g = load_bigendian(statebytes + 48); state[6] = g; 93 | h = load_bigendian(statebytes + 56); state[7] = h; 94 | 95 | while (inlen >= 128) { 96 | uint64 w0 = load_bigendian(in + 0); 97 | uint64 w1 = load_bigendian(in + 8); 98 | uint64 w2 = load_bigendian(in + 16); 99 | uint64 w3 = load_bigendian(in + 24); 100 | uint64 w4 = load_bigendian(in + 32); 101 | uint64 w5 = load_bigendian(in + 40); 102 | uint64 w6 = load_bigendian(in + 48); 103 | uint64 w7 = load_bigendian(in + 56); 104 | uint64 w8 = load_bigendian(in + 64); 105 | uint64 w9 = load_bigendian(in + 72); 106 | uint64 w10 = load_bigendian(in + 80); 107 | uint64 w11 = load_bigendian(in + 88); 108 | uint64 w12 = load_bigendian(in + 96); 109 | uint64 w13 = load_bigendian(in + 104); 110 | uint64 w14 = load_bigendian(in + 112); 111 | uint64 w15 = load_bigendian(in + 120); 112 | 113 | F(w0 ,0x428a2f98d728ae22ULL) 114 | F(w1 ,0x7137449123ef65cdULL) 115 | F(w2 ,0xb5c0fbcfec4d3b2fULL) 116 | F(w3 ,0xe9b5dba58189dbbcULL) 117 | F(w4 ,0x3956c25bf348b538ULL) 118 | F(w5 ,0x59f111f1b605d019ULL) 119 | F(w6 ,0x923f82a4af194f9bULL) 120 | F(w7 ,0xab1c5ed5da6d8118ULL) 121 | F(w8 ,0xd807aa98a3030242ULL) 122 | F(w9 ,0x12835b0145706fbeULL) 123 | F(w10,0x243185be4ee4b28cULL) 124 | F(w11,0x550c7dc3d5ffb4e2ULL) 125 | F(w12,0x72be5d74f27b896fULL) 126 | F(w13,0x80deb1fe3b1696b1ULL) 127 | F(w14,0x9bdc06a725c71235ULL) 128 | F(w15,0xc19bf174cf692694ULL) 129 | 130 | EXPAND 131 | 132 | F(w0 ,0xe49b69c19ef14ad2ULL) 133 | F(w1 ,0xefbe4786384f25e3ULL) 134 | F(w2 ,0x0fc19dc68b8cd5b5ULL) 135 | F(w3 ,0x240ca1cc77ac9c65ULL) 136 | F(w4 ,0x2de92c6f592b0275ULL) 137 | F(w5 ,0x4a7484aa6ea6e483ULL) 138 | F(w6 ,0x5cb0a9dcbd41fbd4ULL) 139 | F(w7 ,0x76f988da831153b5ULL) 140 | F(w8 ,0x983e5152ee66dfabULL) 141 | F(w9 ,0xa831c66d2db43210ULL) 142 | F(w10,0xb00327c898fb213fULL) 143 | F(w11,0xbf597fc7beef0ee4ULL) 144 | F(w12,0xc6e00bf33da88fc2ULL) 145 | F(w13,0xd5a79147930aa725ULL) 146 | F(w14,0x06ca6351e003826fULL) 147 | F(w15,0x142929670a0e6e70ULL) 148 | 149 | EXPAND 150 | 151 | F(w0 ,0x27b70a8546d22ffcULL) 152 | F(w1 ,0x2e1b21385c26c926ULL) 153 | F(w2 ,0x4d2c6dfc5ac42aedULL) 154 | F(w3 ,0x53380d139d95b3dfULL) 155 | F(w4 ,0x650a73548baf63deULL) 156 | F(w5 ,0x766a0abb3c77b2a8ULL) 157 | F(w6 ,0x81c2c92e47edaee6ULL) 158 | F(w7 ,0x92722c851482353bULL) 159 | F(w8 ,0xa2bfe8a14cf10364ULL) 160 | F(w9 ,0xa81a664bbc423001ULL) 161 | F(w10,0xc24b8b70d0f89791ULL) 162 | F(w11,0xc76c51a30654be30ULL) 163 | F(w12,0xd192e819d6ef5218ULL) 164 | F(w13,0xd69906245565a910ULL) 165 | F(w14,0xf40e35855771202aULL) 166 | F(w15,0x106aa07032bbd1b8ULL) 167 | 168 | EXPAND 169 | 170 | F(w0 ,0x19a4c116b8d2d0c8ULL) 171 | F(w1 ,0x1e376c085141ab53ULL) 172 | F(w2 ,0x2748774cdf8eeb99ULL) 173 | F(w3 ,0x34b0bcb5e19b48a8ULL) 174 | F(w4 ,0x391c0cb3c5c95a63ULL) 175 | F(w5 ,0x4ed8aa4ae3418acbULL) 176 | F(w6 ,0x5b9cca4f7763e373ULL) 177 | F(w7 ,0x682e6ff3d6b2b8a3ULL) 178 | F(w8 ,0x748f82ee5defb2fcULL) 179 | F(w9 ,0x78a5636f43172f60ULL) 180 | F(w10,0x84c87814a1f0ab72ULL) 181 | F(w11,0x8cc702081a6439ecULL) 182 | F(w12,0x90befffa23631e28ULL) 183 | F(w13,0xa4506cebde82bde9ULL) 184 | F(w14,0xbef9a3f7b2c67915ULL) 185 | F(w15,0xc67178f2e372532bULL) 186 | 187 | EXPAND 188 | 189 | F(w0 ,0xca273eceea26619cULL) 190 | F(w1 ,0xd186b8c721c0c207ULL) 191 | F(w2 ,0xeada7dd6cde0eb1eULL) 192 | F(w3 ,0xf57d4f7fee6ed178ULL) 193 | F(w4 ,0x06f067aa72176fbaULL) 194 | F(w5 ,0x0a637dc5a2c898a6ULL) 195 | F(w6 ,0x113f9804bef90daeULL) 196 | F(w7 ,0x1b710b35131c471bULL) 197 | F(w8 ,0x28db77f523047d84ULL) 198 | F(w9 ,0x32caab7b40c72493ULL) 199 | F(w10,0x3c9ebe0a15c9bebcULL) 200 | F(w11,0x431d67c49c100d4cULL) 201 | F(w12,0x4cc5d4becb3e42b6ULL) 202 | F(w13,0x597f299cfc657e2aULL) 203 | F(w14,0x5fcb6fab3ad6faecULL) 204 | F(w15,0x6c44198c4a475817ULL) 205 | 206 | a += state[0]; 207 | b += state[1]; 208 | c += state[2]; 209 | d += state[3]; 210 | e += state[4]; 211 | f += state[5]; 212 | g += state[6]; 213 | h += state[7]; 214 | 215 | state[0] = a; 216 | state[1] = b; 217 | state[2] = c; 218 | state[3] = d; 219 | state[4] = e; 220 | state[5] = f; 221 | state[6] = g; 222 | state[7] = h; 223 | 224 | in += 128; 225 | inlen -= 128; 226 | } 227 | 228 | store_bigendian(statebytes + 0,state[0]); 229 | store_bigendian(statebytes + 8,state[1]); 230 | store_bigendian(statebytes + 16,state[2]); 231 | store_bigendian(statebytes + 24,state[3]); 232 | store_bigendian(statebytes + 32,state[4]); 233 | store_bigendian(statebytes + 40,state[5]); 234 | store_bigendian(statebytes + 48,state[6]); 235 | store_bigendian(statebytes + 56,state[7]); 236 | 237 | return 0; 238 | } 239 | -------------------------------------------------------------------------------- /curve/ed25519/nacl_sha512/hash.c: -------------------------------------------------------------------------------- 1 | /* 2 | 20080913 3 | D. J. Bernstein 4 | Public domain. 5 | */ 6 | 7 | #include 8 | typedef uint64_t uint64; 9 | 10 | extern int crypto_hashblocks_sha512(unsigned char *statebytes,const unsigned char *in,unsigned long long inlen); 11 | 12 | #define blocks crypto_hashblocks_sha512 13 | 14 | static const unsigned char iv[64] = { 15 | 0x6a,0x09,0xe6,0x67,0xf3,0xbc,0xc9,0x08, 16 | 0xbb,0x67,0xae,0x85,0x84,0xca,0xa7,0x3b, 17 | 0x3c,0x6e,0xf3,0x72,0xfe,0x94,0xf8,0x2b, 18 | 0xa5,0x4f,0xf5,0x3a,0x5f,0x1d,0x36,0xf1, 19 | 0x51,0x0e,0x52,0x7f,0xad,0xe6,0x82,0xd1, 20 | 0x9b,0x05,0x68,0x8c,0x2b,0x3e,0x6c,0x1f, 21 | 0x1f,0x83,0xd9,0xab,0xfb,0x41,0xbd,0x6b, 22 | 0x5b,0xe0,0xcd,0x19,0x13,0x7e,0x21,0x79 23 | } ; 24 | 25 | int crypto_hash_sha512(unsigned char *out,const unsigned char *in,unsigned long long inlen) 26 | { 27 | unsigned char h[64]; 28 | unsigned char padded[256]; 29 | int i; 30 | unsigned long long bytes = inlen; 31 | 32 | for (i = 0;i < 64;++i) h[i] = iv[i]; 33 | 34 | blocks(h,in,inlen); 35 | in += inlen; 36 | inlen &= 127; 37 | in -= inlen; 38 | 39 | for (i = 0;i < inlen;++i) padded[i] = in[i]; 40 | padded[inlen] = 0x80; 41 | 42 | if (inlen < 112) { 43 | for (i = inlen + 1;i < 119;++i) padded[i] = 0; 44 | padded[119] = bytes >> 61; 45 | padded[120] = bytes >> 53; 46 | padded[121] = bytes >> 45; 47 | padded[122] = bytes >> 37; 48 | padded[123] = bytes >> 29; 49 | padded[124] = bytes >> 21; 50 | padded[125] = bytes >> 13; 51 | padded[126] = bytes >> 5; 52 | padded[127] = bytes << 3; 53 | blocks(h,padded,128); 54 | } else { 55 | for (i = inlen + 1;i < 247;++i) padded[i] = 0; 56 | padded[247] = bytes >> 61; 57 | padded[248] = bytes >> 53; 58 | padded[249] = bytes >> 45; 59 | padded[250] = bytes >> 37; 60 | padded[251] = bytes >> 29; 61 | padded[252] = bytes >> 21; 62 | padded[253] = bytes >> 13; 63 | padded[254] = bytes >> 5; 64 | padded[255] = bytes << 3; 65 | blocks(h,padded,256); 66 | } 67 | 68 | for (i = 0;i < 64;++i) out[i] = h[i]; 69 | 70 | return 0; 71 | } 72 | -------------------------------------------------------------------------------- /curve/ed25519/open.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "crypto_sign.h" 3 | #include "crypto_hash_sha512.h" 4 | #include "crypto_verify_32.h" 5 | #include "ge.h" 6 | #include "sc.h" 7 | 8 | int crypto_sign_open( 9 | unsigned char *m,unsigned long long *mlen, 10 | const unsigned char *sm,unsigned long long smlen, 11 | const unsigned char *pk 12 | ) 13 | { 14 | unsigned char pkcopy[32]; 15 | unsigned char rcopy[32]; 16 | unsigned char scopy[32]; 17 | unsigned char h[64]; 18 | unsigned char rcheck[32]; 19 | ge_p3 A; 20 | ge_p2 R; 21 | 22 | if (smlen < 64) goto badsig; 23 | if (sm[63] & 224) goto badsig; 24 | if (ge_frombytes_negate_vartime(&A,pk) != 0) goto badsig; 25 | 26 | memmove(pkcopy,pk,32); 27 | memmove(rcopy,sm,32); 28 | memmove(scopy,sm + 32,32); 29 | 30 | memmove(m,sm,smlen); 31 | memmove(m + 32,pkcopy,32); 32 | crypto_hash_sha512(h,m,smlen); 33 | sc_reduce(h); 34 | 35 | ge_double_scalarmult_vartime(&R,h,&A,scopy); 36 | ge_tobytes(rcheck,&R); 37 | if (crypto_verify_32(rcheck,rcopy) == 0) { 38 | memmove(m,m + 64,smlen - 64); 39 | memset(m + smlen - 64,0,64); 40 | *mlen = smlen - 64; 41 | return 0; 42 | } 43 | 44 | badsig: 45 | *mlen = -1; 46 | memset(m,0,smlen); 47 | return -1; 48 | } 49 | -------------------------------------------------------------------------------- /curve/ed25519/pow22523.h: -------------------------------------------------------------------------------- 1 | 2 | /* qhasm: fe z1 */ 3 | 4 | /* qhasm: fe z2 */ 5 | 6 | /* qhasm: fe z8 */ 7 | 8 | /* qhasm: fe z9 */ 9 | 10 | /* qhasm: fe z11 */ 11 | 12 | /* qhasm: fe z22 */ 13 | 14 | /* qhasm: fe z_5_0 */ 15 | 16 | /* qhasm: fe z_10_5 */ 17 | 18 | /* qhasm: fe z_10_0 */ 19 | 20 | /* qhasm: fe z_20_10 */ 21 | 22 | /* qhasm: fe z_20_0 */ 23 | 24 | /* qhasm: fe z_40_20 */ 25 | 26 | /* qhasm: fe z_40_0 */ 27 | 28 | /* qhasm: fe z_50_10 */ 29 | 30 | /* qhasm: fe z_50_0 */ 31 | 32 | /* qhasm: fe z_100_50 */ 33 | 34 | /* qhasm: fe z_100_0 */ 35 | 36 | /* qhasm: fe z_200_100 */ 37 | 38 | /* qhasm: fe z_200_0 */ 39 | 40 | /* qhasm: fe z_250_50 */ 41 | 42 | /* qhasm: fe z_250_0 */ 43 | 44 | /* qhasm: fe z_252_2 */ 45 | 46 | /* qhasm: fe z_252_3 */ 47 | 48 | /* qhasm: enter pow22523 */ 49 | 50 | /* qhasm: z2 = z1^2^1 */ 51 | /* asm 1: fe_sq(>z2=fe#1,z2=fe#1,>z2=fe#1); */ 52 | /* asm 2: fe_sq(>z2=t0,z2=t0,>z2=t0); */ 53 | fe_sq(t0,z); for (i = 1;i < 1;++i) fe_sq(t0,t0); 54 | 55 | /* qhasm: z8 = z2^2^2 */ 56 | /* asm 1: fe_sq(>z8=fe#2,z8=fe#2,>z8=fe#2); */ 57 | /* asm 2: fe_sq(>z8=t1,z8=t1,>z8=t1); */ 58 | fe_sq(t1,t0); for (i = 1;i < 2;++i) fe_sq(t1,t1); 59 | 60 | /* qhasm: z9 = z1*z8 */ 61 | /* asm 1: fe_mul(>z9=fe#2,z9=t1,z11=fe#1,z11=t0,z22=fe#1,z22=fe#1,>z22=fe#1); */ 72 | /* asm 2: fe_sq(>z22=t0,z22=t0,>z22=t0); */ 73 | fe_sq(t0,t0); for (i = 1;i < 1;++i) fe_sq(t0,t0); 74 | 75 | /* qhasm: z_5_0 = z9*z22 */ 76 | /* asm 1: fe_mul(>z_5_0=fe#1,z_5_0=t0,z_10_5=fe#2,z_10_5=fe#2,>z_10_5=fe#2); */ 82 | /* asm 2: fe_sq(>z_10_5=t1,z_10_5=t1,>z_10_5=t1); */ 83 | fe_sq(t1,t0); for (i = 1;i < 5;++i) fe_sq(t1,t1); 84 | 85 | /* qhasm: z_10_0 = z_10_5*z_5_0 */ 86 | /* asm 1: fe_mul(>z_10_0=fe#1,z_10_0=t0,z_20_10=fe#2,z_20_10=fe#2,>z_20_10=fe#2); */ 92 | /* asm 2: fe_sq(>z_20_10=t1,z_20_10=t1,>z_20_10=t1); */ 93 | fe_sq(t1,t0); for (i = 1;i < 10;++i) fe_sq(t1,t1); 94 | 95 | /* qhasm: z_20_0 = z_20_10*z_10_0 */ 96 | /* asm 1: fe_mul(>z_20_0=fe#2,z_20_0=t1,z_40_20=fe#3,z_40_20=fe#3,>z_40_20=fe#3); */ 102 | /* asm 2: fe_sq(>z_40_20=t2,z_40_20=t2,>z_40_20=t2); */ 103 | fe_sq(t2,t1); for (i = 1;i < 20;++i) fe_sq(t2,t2); 104 | 105 | /* qhasm: z_40_0 = z_40_20*z_20_0 */ 106 | /* asm 1: fe_mul(>z_40_0=fe#2,z_40_0=t1,z_50_10=fe#2,z_50_10=fe#2,>z_50_10=fe#2); */ 112 | /* asm 2: fe_sq(>z_50_10=t1,z_50_10=t1,>z_50_10=t1); */ 113 | fe_sq(t1,t1); for (i = 1;i < 10;++i) fe_sq(t1,t1); 114 | 115 | /* qhasm: z_50_0 = z_50_10*z_10_0 */ 116 | /* asm 1: fe_mul(>z_50_0=fe#1,z_50_0=t0,z_100_50=fe#2,z_100_50=fe#2,>z_100_50=fe#2); */ 122 | /* asm 2: fe_sq(>z_100_50=t1,z_100_50=t1,>z_100_50=t1); */ 123 | fe_sq(t1,t0); for (i = 1;i < 50;++i) fe_sq(t1,t1); 124 | 125 | /* qhasm: z_100_0 = z_100_50*z_50_0 */ 126 | /* asm 1: fe_mul(>z_100_0=fe#2,z_100_0=t1,z_200_100=fe#3,z_200_100=fe#3,>z_200_100=fe#3); */ 132 | /* asm 2: fe_sq(>z_200_100=t2,z_200_100=t2,>z_200_100=t2); */ 133 | fe_sq(t2,t1); for (i = 1;i < 100;++i) fe_sq(t2,t2); 134 | 135 | /* qhasm: z_200_0 = z_200_100*z_100_0 */ 136 | /* asm 1: fe_mul(>z_200_0=fe#2,z_200_0=t1,z_250_50=fe#2,z_250_50=fe#2,>z_250_50=fe#2); */ 142 | /* asm 2: fe_sq(>z_250_50=t1,z_250_50=t1,>z_250_50=t1); */ 143 | fe_sq(t1,t1); for (i = 1;i < 50;++i) fe_sq(t1,t1); 144 | 145 | /* qhasm: z_250_0 = z_250_50*z_50_0 */ 146 | /* asm 1: fe_mul(>z_250_0=fe#1,z_250_0=t0,z_252_2=fe#1,z_252_2=fe#1,>z_252_2=fe#1); */ 152 | /* asm 2: fe_sq(>z_252_2=t0,z_252_2=t0,>z_252_2=t0); */ 153 | fe_sq(t0,t0); for (i = 1;i < 2;++i) fe_sq(t0,t0); 154 | 155 | /* qhasm: z_252_3 = z_252_2*z1 */ 156 | /* asm 1: fe_mul(>z_252_3=fe#12,z_252_3=out,z2=fe#1,z2=fe#1,>z2=fe#1); */ 52 | /* asm 2: fe_sq(>z2=t0,z2=t0,>z2=t0); */ 53 | fe_sq(t0,z); for (i = 1;i < 1;++i) fe_sq(t0,t0); 54 | 55 | /* qhasm: z8 = z2^2^2 */ 56 | /* asm 1: fe_sq(>z8=fe#2,z8=fe#2,>z8=fe#2); */ 57 | /* asm 2: fe_sq(>z8=t1,z8=t1,>z8=t1); */ 58 | fe_sq(t1,t0); for (i = 1;i < 2;++i) fe_sq(t1,t1); 59 | 60 | /* qhasm: z9 = z1*z8 */ 61 | /* asm 1: fe_mul(>z9=fe#2,z9=t1,z11=fe#1,z11=t0,z22=fe#3,z22=fe#3,>z22=fe#3); */ 72 | /* asm 2: fe_sq(>z22=t2,z22=t2,>z22=t2); */ 73 | fe_sq(t2,t0); for (i = 1;i < 1;++i) fe_sq(t2,t2); 74 | 75 | /* qhasm: z_5_0 = z9*z22 */ 76 | /* asm 1: fe_mul(>z_5_0=fe#2,z_5_0=t1,z_10_5=fe#3,z_10_5=fe#3,>z_10_5=fe#3); */ 82 | /* asm 2: fe_sq(>z_10_5=t2,z_10_5=t2,>z_10_5=t2); */ 83 | fe_sq(t2,t1); for (i = 1;i < 5;++i) fe_sq(t2,t2); 84 | 85 | /* qhasm: z_10_0 = z_10_5*z_5_0 */ 86 | /* asm 1: fe_mul(>z_10_0=fe#2,z_10_0=t1,z_20_10=fe#3,z_20_10=fe#3,>z_20_10=fe#3); */ 92 | /* asm 2: fe_sq(>z_20_10=t2,z_20_10=t2,>z_20_10=t2); */ 93 | fe_sq(t2,t1); for (i = 1;i < 10;++i) fe_sq(t2,t2); 94 | 95 | /* qhasm: z_20_0 = z_20_10*z_10_0 */ 96 | /* asm 1: fe_mul(>z_20_0=fe#3,z_20_0=t2,z_40_20=fe#4,z_40_20=fe#4,>z_40_20=fe#4); */ 102 | /* asm 2: fe_sq(>z_40_20=t3,z_40_20=t3,>z_40_20=t3); */ 103 | fe_sq(t3,t2); for (i = 1;i < 20;++i) fe_sq(t3,t3); 104 | 105 | /* qhasm: z_40_0 = z_40_20*z_20_0 */ 106 | /* asm 1: fe_mul(>z_40_0=fe#3,z_40_0=t2,z_50_10=fe#3,z_50_10=fe#3,>z_50_10=fe#3); */ 112 | /* asm 2: fe_sq(>z_50_10=t2,z_50_10=t2,>z_50_10=t2); */ 113 | fe_sq(t2,t2); for (i = 1;i < 10;++i) fe_sq(t2,t2); 114 | 115 | /* qhasm: z_50_0 = z_50_10*z_10_0 */ 116 | /* asm 1: fe_mul(>z_50_0=fe#2,z_50_0=t1,z_100_50=fe#3,z_100_50=fe#3,>z_100_50=fe#3); */ 122 | /* asm 2: fe_sq(>z_100_50=t2,z_100_50=t2,>z_100_50=t2); */ 123 | fe_sq(t2,t1); for (i = 1;i < 50;++i) fe_sq(t2,t2); 124 | 125 | /* qhasm: z_100_0 = z_100_50*z_50_0 */ 126 | /* asm 1: fe_mul(>z_100_0=fe#3,z_100_0=t2,z_200_100=fe#4,z_200_100=fe#4,>z_200_100=fe#4); */ 132 | /* asm 2: fe_sq(>z_200_100=t3,z_200_100=t3,>z_200_100=t3); */ 133 | fe_sq(t3,t2); for (i = 1;i < 100;++i) fe_sq(t3,t3); 134 | 135 | /* qhasm: z_200_0 = z_200_100*z_100_0 */ 136 | /* asm 1: fe_mul(>z_200_0=fe#3,z_200_0=t2,z_250_50=fe#3,z_250_50=fe#3,>z_250_50=fe#3); */ 142 | /* asm 2: fe_sq(>z_250_50=t2,z_250_50=t2,>z_250_50=t2); */ 143 | fe_sq(t2,t2); for (i = 1;i < 50;++i) fe_sq(t2,t2); 144 | 145 | /* qhasm: z_250_0 = z_250_50*z_50_0 */ 146 | /* asm 1: fe_mul(>z_250_0=fe#2,z_250_0=t1,z_255_5=fe#2,z_255_5=fe#2,>z_255_5=fe#2); */ 152 | /* asm 2: fe_sq(>z_255_5=t1,z_255_5=t1,>z_255_5=t1); */ 153 | fe_sq(t1,t1); for (i = 1;i < 5;++i) fe_sq(t1,t1); 154 | 155 | /* qhasm: z_255_21 = z_255_5*z11 */ 156 | /* asm 1: fe_mul(>z_255_21=fe#12,z_255_21=out,> 5); 39 | crypto_int64 s2 = 2097151 & (load_3(s + 5) >> 2); 40 | crypto_int64 s3 = 2097151 & (load_4(s + 7) >> 7); 41 | crypto_int64 s4 = 2097151 & (load_4(s + 10) >> 4); 42 | crypto_int64 s5 = 2097151 & (load_3(s + 13) >> 1); 43 | crypto_int64 s6 = 2097151 & (load_4(s + 15) >> 6); 44 | crypto_int64 s7 = 2097151 & (load_3(s + 18) >> 3); 45 | crypto_int64 s8 = 2097151 & load_3(s + 21); 46 | crypto_int64 s9 = 2097151 & (load_4(s + 23) >> 5); 47 | crypto_int64 s10 = 2097151 & (load_3(s + 26) >> 2); 48 | crypto_int64 s11 = 2097151 & (load_4(s + 28) >> 7); 49 | crypto_int64 s12 = 2097151 & (load_4(s + 31) >> 4); 50 | crypto_int64 s13 = 2097151 & (load_3(s + 34) >> 1); 51 | crypto_int64 s14 = 2097151 & (load_4(s + 36) >> 6); 52 | crypto_int64 s15 = 2097151 & (load_3(s + 39) >> 3); 53 | crypto_int64 s16 = 2097151 & load_3(s + 42); 54 | crypto_int64 s17 = 2097151 & (load_4(s + 44) >> 5); 55 | crypto_int64 s18 = 2097151 & (load_3(s + 47) >> 2); 56 | crypto_int64 s19 = 2097151 & (load_4(s + 49) >> 7); 57 | crypto_int64 s20 = 2097151 & (load_4(s + 52) >> 4); 58 | crypto_int64 s21 = 2097151 & (load_3(s + 55) >> 1); 59 | crypto_int64 s22 = 2097151 & (load_4(s + 57) >> 6); 60 | crypto_int64 s23 = (load_4(s + 60) >> 3); 61 | crypto_int64 carry0; 62 | crypto_int64 carry1; 63 | crypto_int64 carry2; 64 | crypto_int64 carry3; 65 | crypto_int64 carry4; 66 | crypto_int64 carry5; 67 | crypto_int64 carry6; 68 | crypto_int64 carry7; 69 | crypto_int64 carry8; 70 | crypto_int64 carry9; 71 | crypto_int64 carry10; 72 | crypto_int64 carry11; 73 | crypto_int64 carry12; 74 | crypto_int64 carry13; 75 | crypto_int64 carry14; 76 | crypto_int64 carry15; 77 | crypto_int64 carry16; 78 | 79 | s11 += s23 * 666643; 80 | s12 += s23 * 470296; 81 | s13 += s23 * 654183; 82 | s14 -= s23 * 997805; 83 | s15 += s23 * 136657; 84 | s16 -= s23 * 683901; 85 | s23 = 0; 86 | 87 | s10 += s22 * 666643; 88 | s11 += s22 * 470296; 89 | s12 += s22 * 654183; 90 | s13 -= s22 * 997805; 91 | s14 += s22 * 136657; 92 | s15 -= s22 * 683901; 93 | s22 = 0; 94 | 95 | s9 += s21 * 666643; 96 | s10 += s21 * 470296; 97 | s11 += s21 * 654183; 98 | s12 -= s21 * 997805; 99 | s13 += s21 * 136657; 100 | s14 -= s21 * 683901; 101 | s21 = 0; 102 | 103 | s8 += s20 * 666643; 104 | s9 += s20 * 470296; 105 | s10 += s20 * 654183; 106 | s11 -= s20 * 997805; 107 | s12 += s20 * 136657; 108 | s13 -= s20 * 683901; 109 | s20 = 0; 110 | 111 | s7 += s19 * 666643; 112 | s8 += s19 * 470296; 113 | s9 += s19 * 654183; 114 | s10 -= s19 * 997805; 115 | s11 += s19 * 136657; 116 | s12 -= s19 * 683901; 117 | s19 = 0; 118 | 119 | s6 += s18 * 666643; 120 | s7 += s18 * 470296; 121 | s8 += s18 * 654183; 122 | s9 -= s18 * 997805; 123 | s10 += s18 * 136657; 124 | s11 -= s18 * 683901; 125 | s18 = 0; 126 | 127 | carry6 = (s6 + (1<<20)) >> 21; s7 += carry6; s6 -= carry6 << 21; 128 | carry8 = (s8 + (1<<20)) >> 21; s9 += carry8; s8 -= carry8 << 21; 129 | carry10 = (s10 + (1<<20)) >> 21; s11 += carry10; s10 -= carry10 << 21; 130 | carry12 = (s12 + (1<<20)) >> 21; s13 += carry12; s12 -= carry12 << 21; 131 | carry14 = (s14 + (1<<20)) >> 21; s15 += carry14; s14 -= carry14 << 21; 132 | carry16 = (s16 + (1<<20)) >> 21; s17 += carry16; s16 -= carry16 << 21; 133 | 134 | carry7 = (s7 + (1<<20)) >> 21; s8 += carry7; s7 -= carry7 << 21; 135 | carry9 = (s9 + (1<<20)) >> 21; s10 += carry9; s9 -= carry9 << 21; 136 | carry11 = (s11 + (1<<20)) >> 21; s12 += carry11; s11 -= carry11 << 21; 137 | carry13 = (s13 + (1<<20)) >> 21; s14 += carry13; s13 -= carry13 << 21; 138 | carry15 = (s15 + (1<<20)) >> 21; s16 += carry15; s15 -= carry15 << 21; 139 | 140 | s5 += s17 * 666643; 141 | s6 += s17 * 470296; 142 | s7 += s17 * 654183; 143 | s8 -= s17 * 997805; 144 | s9 += s17 * 136657; 145 | s10 -= s17 * 683901; 146 | s17 = 0; 147 | 148 | s4 += s16 * 666643; 149 | s5 += s16 * 470296; 150 | s6 += s16 * 654183; 151 | s7 -= s16 * 997805; 152 | s8 += s16 * 136657; 153 | s9 -= s16 * 683901; 154 | s16 = 0; 155 | 156 | s3 += s15 * 666643; 157 | s4 += s15 * 470296; 158 | s5 += s15 * 654183; 159 | s6 -= s15 * 997805; 160 | s7 += s15 * 136657; 161 | s8 -= s15 * 683901; 162 | s15 = 0; 163 | 164 | s2 += s14 * 666643; 165 | s3 += s14 * 470296; 166 | s4 += s14 * 654183; 167 | s5 -= s14 * 997805; 168 | s6 += s14 * 136657; 169 | s7 -= s14 * 683901; 170 | s14 = 0; 171 | 172 | s1 += s13 * 666643; 173 | s2 += s13 * 470296; 174 | s3 += s13 * 654183; 175 | s4 -= s13 * 997805; 176 | s5 += s13 * 136657; 177 | s6 -= s13 * 683901; 178 | s13 = 0; 179 | 180 | s0 += s12 * 666643; 181 | s1 += s12 * 470296; 182 | s2 += s12 * 654183; 183 | s3 -= s12 * 997805; 184 | s4 += s12 * 136657; 185 | s5 -= s12 * 683901; 186 | s12 = 0; 187 | 188 | carry0 = (s0 + (1<<20)) >> 21; s1 += carry0; s0 -= carry0 << 21; 189 | carry2 = (s2 + (1<<20)) >> 21; s3 += carry2; s2 -= carry2 << 21; 190 | carry4 = (s4 + (1<<20)) >> 21; s5 += carry4; s4 -= carry4 << 21; 191 | carry6 = (s6 + (1<<20)) >> 21; s7 += carry6; s6 -= carry6 << 21; 192 | carry8 = (s8 + (1<<20)) >> 21; s9 += carry8; s8 -= carry8 << 21; 193 | carry10 = (s10 + (1<<20)) >> 21; s11 += carry10; s10 -= carry10 << 21; 194 | 195 | carry1 = (s1 + (1<<20)) >> 21; s2 += carry1; s1 -= carry1 << 21; 196 | carry3 = (s3 + (1<<20)) >> 21; s4 += carry3; s3 -= carry3 << 21; 197 | carry5 = (s5 + (1<<20)) >> 21; s6 += carry5; s5 -= carry5 << 21; 198 | carry7 = (s7 + (1<<20)) >> 21; s8 += carry7; s7 -= carry7 << 21; 199 | carry9 = (s9 + (1<<20)) >> 21; s10 += carry9; s9 -= carry9 << 21; 200 | carry11 = (s11 + (1<<20)) >> 21; s12 += carry11; s11 -= carry11 << 21; 201 | 202 | s0 += s12 * 666643; 203 | s1 += s12 * 470296; 204 | s2 += s12 * 654183; 205 | s3 -= s12 * 997805; 206 | s4 += s12 * 136657; 207 | s5 -= s12 * 683901; 208 | s12 = 0; 209 | 210 | carry0 = s0 >> 21; s1 += carry0; s0 -= carry0 << 21; 211 | carry1 = s1 >> 21; s2 += carry1; s1 -= carry1 << 21; 212 | carry2 = s2 >> 21; s3 += carry2; s2 -= carry2 << 21; 213 | carry3 = s3 >> 21; s4 += carry3; s3 -= carry3 << 21; 214 | carry4 = s4 >> 21; s5 += carry4; s4 -= carry4 << 21; 215 | carry5 = s5 >> 21; s6 += carry5; s5 -= carry5 << 21; 216 | carry6 = s6 >> 21; s7 += carry6; s6 -= carry6 << 21; 217 | carry7 = s7 >> 21; s8 += carry7; s7 -= carry7 << 21; 218 | carry8 = s8 >> 21; s9 += carry8; s8 -= carry8 << 21; 219 | carry9 = s9 >> 21; s10 += carry9; s9 -= carry9 << 21; 220 | carry10 = s10 >> 21; s11 += carry10; s10 -= carry10 << 21; 221 | carry11 = s11 >> 21; s12 += carry11; s11 -= carry11 << 21; 222 | 223 | s0 += s12 * 666643; 224 | s1 += s12 * 470296; 225 | s2 += s12 * 654183; 226 | s3 -= s12 * 997805; 227 | s4 += s12 * 136657; 228 | s5 -= s12 * 683901; 229 | s12 = 0; 230 | 231 | carry0 = s0 >> 21; s1 += carry0; s0 -= carry0 << 21; 232 | carry1 = s1 >> 21; s2 += carry1; s1 -= carry1 << 21; 233 | carry2 = s2 >> 21; s3 += carry2; s2 -= carry2 << 21; 234 | carry3 = s3 >> 21; s4 += carry3; s3 -= carry3 << 21; 235 | carry4 = s4 >> 21; s5 += carry4; s4 -= carry4 << 21; 236 | carry5 = s5 >> 21; s6 += carry5; s5 -= carry5 << 21; 237 | carry6 = s6 >> 21; s7 += carry6; s6 -= carry6 << 21; 238 | carry7 = s7 >> 21; s8 += carry7; s7 -= carry7 << 21; 239 | carry8 = s8 >> 21; s9 += carry8; s8 -= carry8 << 21; 240 | carry9 = s9 >> 21; s10 += carry9; s9 -= carry9 << 21; 241 | carry10 = s10 >> 21; s11 += carry10; s10 -= carry10 << 21; 242 | 243 | s[0] = s0 >> 0; 244 | s[1] = s0 >> 8; 245 | s[2] = (s0 >> 16) | (s1 << 5); 246 | s[3] = s1 >> 3; 247 | s[4] = s1 >> 11; 248 | s[5] = (s1 >> 19) | (s2 << 2); 249 | s[6] = s2 >> 6; 250 | s[7] = (s2 >> 14) | (s3 << 7); 251 | s[8] = s3 >> 1; 252 | s[9] = s3 >> 9; 253 | s[10] = (s3 >> 17) | (s4 << 4); 254 | s[11] = s4 >> 4; 255 | s[12] = s4 >> 12; 256 | s[13] = (s4 >> 20) | (s5 << 1); 257 | s[14] = s5 >> 7; 258 | s[15] = (s5 >> 15) | (s6 << 6); 259 | s[16] = s6 >> 2; 260 | s[17] = s6 >> 10; 261 | s[18] = (s6 >> 18) | (s7 << 3); 262 | s[19] = s7 >> 5; 263 | s[20] = s7 >> 13; 264 | s[21] = s8 >> 0; 265 | s[22] = s8 >> 8; 266 | s[23] = (s8 >> 16) | (s9 << 5); 267 | s[24] = s9 >> 3; 268 | s[25] = s9 >> 11; 269 | s[26] = (s9 >> 19) | (s10 << 2); 270 | s[27] = s10 >> 6; 271 | s[28] = (s10 >> 14) | (s11 << 7); 272 | s[29] = s11 >> 1; 273 | s[30] = s11 >> 9; 274 | s[31] = s11 >> 17; 275 | } 276 | -------------------------------------------------------------------------------- /curve/ed25519/sign.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "crypto_sign.h" 3 | #include "crypto_hash_sha512.h" 4 | #include "ge.h" 5 | #include "sc.h" 6 | 7 | int crypto_sign( 8 | unsigned char *sm,unsigned long long *smlen, 9 | const unsigned char *m,unsigned long long mlen, 10 | const unsigned char *sk 11 | ) 12 | { 13 | unsigned char pk[32]; 14 | unsigned char az[64]; 15 | unsigned char nonce[64]; 16 | unsigned char hram[64]; 17 | ge_p3 R; 18 | 19 | memmove(pk,sk + 32,32); 20 | 21 | crypto_hash_sha512(az,sk,32); 22 | az[0] &= 248; 23 | az[31] &= 63; 24 | az[31] |= 64; 25 | 26 | *smlen = mlen + 64; 27 | memmove(sm + 64,m,mlen); 28 | memmove(sm + 32,az + 32,32); 29 | crypto_hash_sha512(nonce,sm + 32,mlen + 32); 30 | memmove(sm + 32,pk,32); 31 | 32 | sc_reduce(nonce); 33 | ge_scalarmult_base(&R,nonce); 34 | ge_p3_tobytes(sm,&R); 35 | 36 | crypto_hash_sha512(hram,sm,mlen + 64); 37 | sc_reduce(hram); 38 | sc_muladd(sm + 32,hram,az,nonce); 39 | 40 | return 0; 41 | } 42 | -------------------------------------------------------------------------------- /curve/ed25519/sqrtm1.h: -------------------------------------------------------------------------------- 1 | -32595792,-7943725,9377950,3500415,12389472,-272473,-25146209,-2005654,326686,11406482 2 | -------------------------------------------------------------------------------- /curve/ed25519/tests/internal_fast_tests.h: -------------------------------------------------------------------------------- 1 | #ifndef __INTERNAL_FAST_TESTS_H__ 2 | #define __INTERNAL_FAST_TESTS_H__ 3 | 4 | /* silent = 0 : prints info+error messages to stdout, abort() on test failure 5 | * silent = 1 : returns 0 for success, anything else for failure 6 | */ 7 | 8 | int sha512_fast_test(int silent); 9 | int strict_fast_test(int silent); 10 | int elligator_fast_test(int silent); 11 | int curvesigs_fast_test(int silent); 12 | int xeddsa_fast_test(int silent); 13 | int vxeddsa_fast_test(int silent); 14 | int generalized_xeddsa_fast_test(int silent); 15 | int generalized_xveddsa_fast_test(int silent); 16 | 17 | int all_fast_tests(int silent); 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /curve/ed25519/tests/internal_slow_tests.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "crypto_hash_sha512.h" 5 | #include "keygen.h" 6 | #include "curve_sigs.h" 7 | #include "xeddsa.h" 8 | #include "crypto_additions.h" 9 | #include "ge.h" 10 | #include "utility.h" 11 | #include "gen_x.h" 12 | #include "internal_slow_tests.h" 13 | #include 14 | 15 | 16 | #define ERROR(...) do {if (!silent) { printf(__VA_ARGS__); abort(); } else return -1; } while (0) 17 | #define INFO(...) do {if (!silent) printf(__VA_ARGS__);} while (0) 18 | 19 | #define TEST(msg, cond) \ 20 | do { \ 21 | if ((cond)) { \ 22 | INFO("%s good\n", msg); \ 23 | } \ 24 | else { \ 25 | ERROR("%s BAD!!!\n", msg); \ 26 | } \ 27 | } while (0) 28 | 29 | 30 | 31 | int curvesigs_slow_test(int silent, int iterations) 32 | { 33 | 34 | unsigned char signature_10k_correct[64] = { 35 | 0xfc, 0xba, 0x55, 0xc4, 0x85, 0x4a, 0x42, 0x25, 36 | 0x19, 0xab, 0x08, 0x8d, 0xfe, 0xb5, 0x13, 0xb6, 37 | 0x0d, 0x24, 0xbb, 0x16, 0x27, 0x55, 0x71, 0x48, 38 | 0xdd, 0x20, 0xb1, 0xcd, 0x2a, 0xd6, 0x7e, 0x35, 39 | 0xef, 0x33, 0x4c, 0x7b, 0x6d, 0x94, 0x6f, 0x52, 40 | 0xec, 0x43, 0xd7, 0xe6, 0x35, 0x24, 0xcd, 0x5b, 41 | 0x5d, 0xdc, 0xb2, 0x32, 0xc6, 0x22, 0x53, 0xf3, 42 | 0x38, 0x02, 0xf8, 0x28, 0x28, 0xc5, 0x65, 0x05, 43 | }; 44 | 45 | int count; 46 | const int MSG_LEN = 200; 47 | unsigned char privkey[32]; 48 | unsigned char pubkey[32]; 49 | unsigned char signature[64]; 50 | unsigned char msg[MSG_LEN]; 51 | unsigned char random[64]; 52 | 53 | memset(privkey, 0, 32); 54 | memset(pubkey, 0, 32); 55 | memset(signature, 0, 64); 56 | memset(msg, 0, MSG_LEN); 57 | memset(random, 0, 64); 58 | 59 | /* Signature random test */ 60 | INFO("Pseudorandom curvesigs...\n"); 61 | for (count = 1; count <= iterations; count++) { 62 | unsigned char b[64]; 63 | crypto_hash_sha512(b, signature, 64); 64 | memmove(privkey, b, 32); 65 | crypto_hash_sha512(b, privkey, 32); 66 | memmove(random, b, 64); 67 | 68 | sc_clamp(privkey); 69 | curve25519_keygen(pubkey, privkey); 70 | 71 | curve25519_sign(signature, privkey, msg, MSG_LEN, random); 72 | 73 | if (curve25519_verify(signature, pubkey, msg, MSG_LEN) != 0) 74 | ERROR("Curvesig verify failure #1 %d\n", count); 75 | 76 | if (b[63] & 1) 77 | signature[count % 64] ^= 1; 78 | else 79 | msg[count % MSG_LEN] ^= 1; 80 | if (curve25519_verify(signature, pubkey, msg, MSG_LEN) == 0) 81 | ERROR("Curvesig verify failure #2 %d\n", count); 82 | 83 | if (count == 10000) { 84 | if (memcmp(signature, signature_10k_correct, 64) != 0) 85 | ERROR("Curvesig signature 10K doesn't match %d\n", count); 86 | } 87 | if (count == 100000) 88 | print_bytes("100K curvesigs", signature, 64); 89 | if (count == 1000000) 90 | print_bytes("1M curvesigs", signature, 64); 91 | if (count == 10000000) 92 | print_bytes("10M curvesigs", signature, 64); 93 | } 94 | INFO("good\n"); 95 | return 0; 96 | } 97 | 98 | int xeddsa_slow_test(int silent, int iterations) 99 | { 100 | 101 | unsigned char signature_10k_correct[64] = { 102 | 0x15, 0x29, 0x03, 0x38, 0x66, 0x16, 0xcd, 0x26, 103 | 0xbb, 0x3e, 0xec, 0xe2, 0x9f, 0x72, 0xa2, 0x5c, 104 | 0x7d, 0x05, 0xc9, 0xcb, 0x84, 0x3f, 0x92, 0x96, 105 | 0xb3, 0xfb, 0xb9, 0xdd, 0xd6, 0xed, 0x99, 0x04, 106 | 0xc1, 0xa8, 0x02, 0x16, 0xcf, 0x49, 0x3f, 0xf1, 107 | 0xbe, 0x69, 0xf9, 0xf1, 0xcc, 0x16, 0xd7, 0xdc, 108 | 0x6e, 0xd3, 0x78, 0xaa, 0x04, 0xeb, 0x71, 0x51, 109 | 0x9d, 0xe8, 0x7a, 0x5b, 0xd8, 0x49, 0x7b, 0x05, 110 | }; 111 | 112 | int count; 113 | const int MSG_LEN = 200; 114 | unsigned char privkey[32]; 115 | unsigned char pubkey[32]; 116 | unsigned char signature[96]; 117 | unsigned char msg[MSG_LEN]; 118 | unsigned char random[64]; 119 | 120 | memset(privkey, 0, 32); 121 | memset(pubkey, 0, 32); 122 | memset(signature, 1, 64); 123 | memset(msg, 0, MSG_LEN); 124 | memset(random, 0, 64); 125 | 126 | /* Signature random test */ 127 | INFO("Pseudorandom XEdDSA...\n"); 128 | for (count = 1; count <= iterations; count++) { 129 | unsigned char b[64]; 130 | crypto_hash_sha512(b, signature, 64); 131 | memmove(privkey, b, 32); 132 | crypto_hash_sha512(b, privkey, 32); 133 | memmove(random, b, 64); 134 | 135 | sc_clamp(privkey); 136 | curve25519_keygen(pubkey, privkey); 137 | 138 | xed25519_sign(signature, privkey, msg, MSG_LEN, random); 139 | 140 | if (xed25519_verify(signature, pubkey, msg, MSG_LEN) != 0) 141 | ERROR("XEdDSA verify failure #1 %d\n", count); 142 | 143 | if (b[63] & 1) 144 | signature[count % 64] ^= 1; 145 | else 146 | msg[count % MSG_LEN] ^= 1; 147 | if (xed25519_verify(signature, pubkey, msg, MSG_LEN) == 0) 148 | ERROR("XEdDSA verify failure #2 %d\n", count); 149 | 150 | if (count == 10000) { 151 | if (memcmp(signature, signature_10k_correct, 64) != 0) 152 | ERROR("XEDSA signature 10K doesn't match %d\n", count); 153 | } 154 | if (count == 100000) 155 | print_bytes("100K XEdDSA", signature, 64); 156 | if (count == 1000000) 157 | print_bytes("1M XEdDSA", signature, 64); 158 | if (count == 10000000) 159 | print_bytes("10M XEdDSA", signature, 64); 160 | } 161 | INFO("good\n"); 162 | return 0; 163 | } 164 | 165 | int xeddsa_to_curvesigs_slow_test(int silent, int iterations) 166 | { 167 | unsigned char signature_10k_correct[64] = { 168 | 0x33, 0x50, 0xa8, 0x68, 0xcd, 0x9e, 0x74, 0x99, 169 | 0xa3, 0x5c, 0x33, 0x75, 0x2b, 0x22, 0x03, 0xf8, 170 | 0xb5, 0x0f, 0xea, 0x8c, 0x33, 0x1c, 0x68, 0x8b, 171 | 0xbb, 0xf3, 0x31, 0xcf, 0x7c, 0x42, 0x37, 0x35, 172 | 0xa0, 0x0e, 0x15, 0xb8, 0x5d, 0x2b, 0xe1, 0xa2, 173 | 0x03, 0x77, 0x94, 0x3d, 0x13, 0x5c, 0xd4, 0x9b, 174 | 0x6a, 0x31, 0xf4, 0xdc, 0xfe, 0x24, 0xad, 0x54, 175 | 0xeb, 0xd2, 0x98, 0x47, 0xf1, 0xcc, 0xbf, 0x0d 176 | 177 | }; 178 | 179 | int count; 180 | const int MSG_LEN = 200; 181 | unsigned char privkey[32]; 182 | unsigned char pubkey[32]; 183 | unsigned char signature[96]; 184 | unsigned char msg[MSG_LEN]; 185 | unsigned char random[64]; 186 | 187 | memset(privkey, 0, 32); 188 | memset(pubkey, 0, 32); 189 | memset(signature, 2, 64); 190 | memset(msg, 0, MSG_LEN); 191 | memset(random, 0, 64); 192 | 193 | /* Signature random test */ 194 | INFO("Pseudorandom XEdDSA/Curvesigs...\n"); 195 | for (count = 1; count <= iterations; count++) { 196 | unsigned char b[64]; 197 | crypto_hash_sha512(b, signature, 64); 198 | memmove(privkey, b, 32); 199 | crypto_hash_sha512(b, privkey, 32); 200 | memmove(random, b, 64); 201 | 202 | sc_clamp(privkey); 203 | curve25519_keygen(pubkey, privkey); 204 | 205 | xed25519_sign(signature, privkey, msg, MSG_LEN, random); 206 | 207 | if (curve25519_verify(signature, pubkey, msg, MSG_LEN) != 0) 208 | ERROR("XEdDSA/Curvesigs verify failure #1 %d\n", count); 209 | 210 | if (b[63] & 1) 211 | signature[count % 64] ^= 1; 212 | else 213 | msg[count % MSG_LEN] ^= 1; 214 | if (curve25519_verify(signature, pubkey, msg, MSG_LEN) == 0) 215 | ERROR("XEdDSA/Curvesigs verify failure #2 %d\n", count); 216 | 217 | if (count == 10000) { 218 | if (memcmp(signature, signature_10k_correct, 64) != 0) 219 | ERROR("XEdDSA/Curvesigs signature 10K doesn't match %d\n", count); 220 | } 221 | if (count == 100000) 222 | print_bytes("100K XEdDSA/C", signature, 64); 223 | if (count == 1000000) 224 | print_bytes("1M XEdDSA/C", signature, 64); 225 | if (count == 10000000) 226 | print_bytes("10M XEdDSA/C", signature, 64); 227 | } 228 | INFO("good\n"); 229 | return 0; 230 | } 231 | 232 | int generalized_xveddsa_slow_test(int silent, int iterations) 233 | { 234 | unsigned char signature_10k_correct[96] = { 235 | 0x89, 0x21, 0xf5, 0x2f, 0x37, 0x72, 0x08, 0x55, 236 | 0x18, 0x9d, 0x24, 0xed, 0x86, 0xb1, 0x7a, 0x02, 237 | 0xbf, 0x29, 0x5e, 0xa7, 0x45, 0xdc, 0x80, 0x03, 238 | 0x7f, 0x4f, 0xca, 0x79, 0xe0, 0x95, 0xd0, 0xa1, 239 | 0xb5, 0x99, 0xbe, 0xbd, 0xef, 0xbe, 0xa4, 0xdc, 240 | 0x0c, 0x07, 0x6a, 0xf7, 0x7f, 0xe1, 0x1c, 0xb8, 241 | 0x18, 0x84, 0xb8, 0xb4, 0xcf, 0x38, 0x7d, 0x98, 242 | 0x37, 0xd8, 0x40, 0x23, 0x42, 0x12, 0x70, 0x06, 243 | 0xb0, 0xd1, 0x0c, 0xc0, 0x1c, 0xa6, 0x9a, 0x2f, 244 | 0xb4, 0x02, 0xd6, 0x37, 0x22, 0xe9, 0xfb, 0x00, 245 | 0x22, 0x02, 0x5a, 0xf4, 0x40, 0x43, 0xb8, 0xe9, 246 | 0xf4, 0x13, 0x44, 0x16, 0x19, 0x8d, 0x7e, 0x02, 247 | }; 248 | unsigned char signature_100k_correct[96] = { 249 | 0xc4, 0x99, 0x64, 0x1f, 0x94, 0x95, 0xf4, 0x57, 250 | 0xa0, 0xb9, 0x3d, 0xc3, 0xb5, 0x2e, 0x1e, 0xdd, 251 | 0x92, 0xf2, 0x4c, 0xb2, 0x01, 0x36, 0x3d, 0xf2, 252 | 0xea, 0x2c, 0xdc, 0x32, 0x21, 0x5f, 0xc5, 0xd2, 253 | 0xff, 0x16, 0x41, 0x71, 0x3a, 0x77, 0x79, 0xeb, 254 | 0x67, 0x20, 0xc4, 0xec, 0x39, 0xe1, 0x54, 0x2d, 255 | 0x40, 0x10, 0xf9, 0xca, 0xc5, 0x21, 0x0a, 0x47, 256 | 0x63, 0x99, 0x23, 0x04, 0x9d, 0x03, 0x1a, 0x06, 257 | 0x00, 0xb9, 0x56, 0x7e, 0xef, 0xee, 0x0b, 0x40, 258 | 0x59, 0xc1, 0x86, 0xd9, 0xa7, 0x87, 0x70, 0xec, 259 | 0x05, 0x89, 0xbe, 0x71, 0x43, 0xd1, 0xf5, 0x61, 260 | 0x5e, 0x00, 0x41, 0xde, 0x1f, 0x41, 0x2d, 0x0e, 261 | }; 262 | 263 | 264 | /* 265 | unsigned char signature_1m_correct[96] = { 266 | 0xf8, 0xb1, 0x20, 0xf2, 0x1e, 0x5c, 0xbf, 0x5f, 267 | 0xea, 0x07, 0xcb, 0xb5, 0x77, 0xb8, 0x03, 0xbc, 268 | 0xcb, 0x6d, 0xf1, 0xc1, 0xa5, 0x03, 0x05, 0x7b, 269 | 0x01, 0x63, 0x9b, 0xf9, 0xed, 0x3e, 0x57, 0x47, 270 | 0xd2, 0x5b, 0xf4, 0x7e, 0x7c, 0x45, 0xce, 0xfc, 271 | 0x06, 0xb3, 0xf4, 0x05, 0x81, 0x9f, 0x53, 0xb0, 272 | 0x18, 0xe3, 0xfa, 0xcb, 0xb2, 0x52, 0x3e, 0x57, 273 | 0xcb, 0x34, 0xcc, 0x81, 0x60, 0xb9, 0x0b, 0x04, 274 | 0x07, 0x79, 0xc0, 0x53, 0xad, 0xc4, 0x4b, 0xd0, 275 | 0xb5, 0x7d, 0x95, 0x4e, 0xbe, 0xa5, 0x75, 0x0c, 276 | 0xd4, 0xbf, 0xa7, 0xc0, 0xcf, 0xba, 0xe7, 0x7c, 277 | 0xe2, 0x90, 0xef, 0x61, 0xa9, 0x29, 0x66, 0x0d, 278 | }; 279 | 280 | unsigned char signature_10m_correct[96] = { 281 | 0xf5, 0xa4, 0xbc, 0xec, 0xc3, 0x3d, 0xd0, 0x43, 282 | 0xd2, 0x81, 0x27, 0x9e, 0xf0, 0x4c, 0xbe, 0xf3, 283 | 0x77, 0x01, 0x56, 0x41, 0x0e, 0xff, 0x0c, 0xb9, 284 | 0x66, 0xec, 0x4d, 0xe0, 0xb7, 0x25, 0x63, 0x6b, 285 | 0x5c, 0x08, 0x39, 0x80, 0x4e, 0x37, 0x1b, 0x2c, 286 | 0x46, 0x6f, 0x86, 0x99, 0x1c, 0x4e, 0x31, 0x60, 287 | 0xdb, 0x4c, 0xfe, 0xc5, 0xa2, 0x4d, 0x71, 0x2b, 288 | 0xd6, 0xd0, 0xc3, 0x98, 0x88, 0xdb, 0x0e, 0x0c, 289 | 0x68, 0x4a, 0xd3, 0xc7, 0x56, 0xac, 0x8d, 0x95, 290 | 0x7b, 0xbd, 0x99, 0x50, 0xe8, 0xd3, 0xea, 0xf3, 291 | 0x7b, 0x26, 0xf2, 0xa2, 0x2b, 0x02, 0x58, 0xca, 292 | 0xbd, 0x2c, 0x2b, 0xf7, 0x77, 0x58, 0xfe, 0x09, 293 | }; 294 | */ 295 | 296 | int count; 297 | const int MSG_LEN = 200; 298 | unsigned char privkey[32]; 299 | unsigned char pubkey[32]; 300 | unsigned char signature[96]; 301 | unsigned char msg[MSG_LEN]; 302 | unsigned char random[64]; 303 | unsigned char vrf_out[32]; 304 | 305 | memset(privkey, 0, 32); 306 | memset(pubkey, 0, 32); 307 | memset(signature, 3, 96); 308 | memset(msg, 0, MSG_LEN); 309 | memset(random, 0, 64); 310 | 311 | INFO("Pseudorandom XVEdDSA...\n"); 312 | for (count = 1; count <= iterations; count++) { 313 | unsigned char b[64]; 314 | crypto_hash_sha512(b, signature, 96); 315 | memmove(privkey, b, 32); 316 | crypto_hash_sha512(b, privkey, 32); 317 | memmove(random, b, 64); 318 | 319 | sc_clamp(privkey); 320 | curve25519_keygen(pubkey, privkey); 321 | 322 | generalized_xveddsa_25519_sign(signature, privkey, msg, MSG_LEN, random, NULL, 0); 323 | 324 | if (generalized_xveddsa_25519_verify(vrf_out, signature, pubkey, msg, MSG_LEN, NULL, 0) != 0) 325 | ERROR("XVEdDSA verify failure #1 %d\n", count); 326 | 327 | if (b[63] & 1) 328 | signature[count % 96] ^= 1; 329 | else 330 | msg[count % MSG_LEN] ^= 1; 331 | 332 | if (generalized_xveddsa_25519_verify(vrf_out, signature, pubkey, msg, MSG_LEN, NULL, 0) == 0) 333 | ERROR("XVEdDSA verify failure #2 %d\n", count); 334 | 335 | if (count == 10000) 336 | print_bytes("10K XVEdDSA", signature, 96); 337 | if (count == 100000) 338 | print_bytes("100K XVEdDSA", signature, 96); 339 | if (count == 1000000) 340 | print_bytes("1M XVEdDSA", signature, 96); 341 | if (count == 10000000) 342 | print_bytes("10M XVEdDSA", signature, 96); 343 | if (count == 100000000) 344 | print_bytes("100M XVEdDSA", signature, 96); 345 | 346 | if (count == 10000) { 347 | if (memcmp(signature, signature_10k_correct, 96) != 0) 348 | ERROR("XVEDDSA 10K doesn't match %d\n", count); 349 | } 350 | if (count == 100000) { 351 | if (memcmp(signature, signature_100k_correct, 96) != 0) 352 | ERROR("XVEDDSA 100K doesn't match %d\n", count); 353 | } 354 | /* 355 | if (count == 1000000) { 356 | if (memcmp(signature, signature_1m_correct, 96) != 0) 357 | ERROR("XVEDDSA 1m doesn't match %d\n", count); 358 | } 359 | if (count == 10000000) { 360 | if (memcmp(signature, signature_10m_correct, 96) != 0) 361 | ERROR("XVEDDSA 10m doesn't match %d\n", count); 362 | } 363 | if (count == 100000000) { 364 | if (memcmp(signature, signature_100m_correct, 96) != 0) 365 | ERROR("XVEDDSA 100m doesn't match %d\n", count); 366 | } 367 | */ 368 | } 369 | INFO("good\n"); 370 | return 0; 371 | } 372 | -------------------------------------------------------------------------------- /curve/ed25519/tests/internal_slow_tests.h: -------------------------------------------------------------------------------- 1 | #ifndef __INTERNAL_SLOW_TESTS_H__ 2 | #define __INTERNAL_SLOW_TESTS_H__ 3 | 4 | /* silent = 0 : prints info+error messages to stdout, abort() on test failure 5 | * silent = 1 : returns 0 for success, anything else for failure 6 | * iterations : hardcoded known-good values are at 10000, so run at least this many 7 | */ 8 | 9 | int curvesigs_slow_test(int silent, int iterations); 10 | int xeddsa_slow_test(int silent, int iterations); 11 | int xeddsa_to_curvesigs_slow_test(int silent, int iterations); 12 | int generalized_xveddsa_slow_test(int silent, int iterations); 13 | 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /curve25519module.c: -------------------------------------------------------------------------------- 1 | /* tell python that PyArg_ParseTuple(t#) means Py_ssize_t, not int */ 2 | #define PY_SSIZE_T_CLEAN 3 | #include 4 | #if (PY_VERSION_HEX < 0x02050000) 5 | typedef int Py_ssize_t; 6 | #endif 7 | 8 | /* This is required for compatibility with Python 2. */ 9 | #if PY_MAJOR_VERSION >= 3 10 | #include 11 | #define y "y" 12 | #else 13 | #define PyBytes_FromStringAndSize PyString_FromStringAndSize 14 | #define y "t" 15 | #endif 16 | 17 | int curve25519_sign(unsigned char* signature_out, 18 | const unsigned char* curve25519_privkey, 19 | const unsigned char* msg, const unsigned long msg_len, 20 | const unsigned char* random); 21 | 22 | int curve25519_verify(const unsigned char* signature, 23 | const unsigned char* curve25519_pubkey, 24 | const unsigned char* msg, const unsigned long msg_len); 25 | 26 | 27 | int curve25519_donna(char *mypublic, 28 | const char *secret, const char *basepoint); 29 | 30 | static PyObject * 31 | calculateSignature(PyObject *self, PyObject *args) 32 | { 33 | const char *random; 34 | const char *privatekey; 35 | const char *message; 36 | char signature[64]; 37 | Py_ssize_t randomlen, privatekeylen, messagelen; 38 | 39 | if (!PyArg_ParseTuple(args, y"#"y"#"y"#:generate",&random, &randomlen, &privatekey, &privatekeylen, &message, &messagelen)) 40 | return NULL; 41 | if (privatekeylen != 32) { 42 | PyErr_SetString(PyExc_ValueError, "private key must be 32-byte string" ); 43 | return NULL; 44 | } 45 | if (randomlen != 64) { 46 | PyErr_SetString(PyExc_ValueError, "random must be 64-byte string"); 47 | return NULL; 48 | } 49 | 50 | curve25519_sign((unsigned char *)signature, (unsigned char *)privatekey, 51 | (unsigned char *)message, messagelen, (unsigned char *)random); 52 | 53 | return PyBytes_FromStringAndSize((char *)signature, 64); 54 | } 55 | 56 | static PyObject * 57 | verifySignature(PyObject *self, PyObject *args) 58 | { 59 | const char *publickey; 60 | const char *message; 61 | const char *signature; 62 | 63 | Py_ssize_t publickeylen, messagelen, signaturelen; 64 | 65 | if (!PyArg_ParseTuple(args, y"#"y"#"y"#:generate", &publickey, &publickeylen, &message, &messagelen, &signature, &signaturelen)) 66 | return NULL; 67 | 68 | if (publickeylen != 32) { 69 | PyErr_SetString(PyExc_ValueError, "publickey must be 32-byte string"); 70 | return NULL; 71 | } 72 | if (signaturelen != 64) { 73 | PyErr_SetString(PyExc_ValueError, "signature must be 64-byte string"); 74 | return NULL; 75 | } 76 | 77 | int result = curve25519_verify((unsigned char *)signature, (unsigned char *)publickey, 78 | (unsigned char *)message, messagelen); 79 | 80 | return Py_BuildValue("i", result); 81 | 82 | } 83 | 84 | static PyObject * 85 | generatePrivateKey(PyObject *self, PyObject *args) 86 | { 87 | char *random; 88 | Py_ssize_t randomlen; 89 | 90 | if(!PyArg_ParseTuple(args, y"#:clamp", &random, &randomlen)) { 91 | return NULL; 92 | } 93 | 94 | if(randomlen != 32) { 95 | PyErr_SetString(PyExc_ValueError, "random must be 32-byte string"); 96 | return NULL; 97 | } 98 | random[0] &= 248; 99 | random[31] &= 127; 100 | random[31] |= 64; 101 | 102 | return PyBytes_FromStringAndSize((char *)random, 32); 103 | } 104 | 105 | static PyObject * 106 | generatePublicKey(PyObject *self, PyObject *args) 107 | { 108 | const char *private; 109 | char mypublic[32]; 110 | char basepoint[32] = {9}; 111 | Py_ssize_t privatelen; 112 | if (!PyArg_ParseTuple(args, y"#:makepublic", &private, &privatelen)) 113 | return NULL; 114 | if (privatelen != 32) { 115 | PyErr_SetString(PyExc_ValueError, "input must be 32-byte string"); 116 | return NULL; 117 | } 118 | curve25519_donna(mypublic, private, basepoint); 119 | return PyBytes_FromStringAndSize((char *)mypublic, 32); 120 | } 121 | 122 | static PyObject * 123 | calculateAgreement(PyObject *self, PyObject *args) 124 | { 125 | const char *myprivate, *theirpublic; 126 | char shared_key[32]; 127 | Py_ssize_t myprivatelen, theirpubliclen; 128 | if (!PyArg_ParseTuple(args, y"#"y"#:generate", 129 | &myprivate, &myprivatelen, &theirpublic, &theirpubliclen)) 130 | return NULL; 131 | if (myprivatelen != 32) { 132 | PyErr_SetString(PyExc_ValueError, "input must be 32-byte string"); 133 | return NULL; 134 | } 135 | if (theirpubliclen != 32) { 136 | PyErr_SetString(PyExc_ValueError, "input must be 32-byte string"); 137 | return NULL; 138 | } 139 | curve25519_donna(shared_key, myprivate, theirpublic); 140 | return PyBytes_FromStringAndSize((char *)shared_key, 32); 141 | } 142 | 143 | 144 | static PyMethodDef 145 | curve25519_functions[] = { 146 | {"calculateSignature", calculateSignature, METH_VARARGS, "random+privatekey+message->signature"}, 147 | {"verifySignature", verifySignature, METH_VARARGS, "publickey+message+signature->valid"}, 148 | {"generatePrivateKey", generatePrivateKey, METH_VARARGS, "data->private"}, 149 | {"generatePublicKey", generatePublicKey, METH_VARARGS, "private->public"}, 150 | {"calculateAgreement", calculateAgreement, METH_VARARGS, "private+public->shared"}, 151 | {NULL, NULL, 0, NULL}, 152 | }; 153 | 154 | 155 | #if PY_MAJOR_VERSION >= 3 156 | static struct PyModuleDef 157 | curve25519_module = { 158 | PyModuleDef_HEAD_INIT, 159 | "axolotl_curve25519", 160 | NULL, 161 | NULL, 162 | curve25519_functions, 163 | }; 164 | 165 | PyObject * 166 | PyInit_axolotl_curve25519(void) 167 | { 168 | return PyModule_Create(&curve25519_module); 169 | } 170 | #else 171 | 172 | PyMODINIT_FUNC 173 | initaxolotl_curve25519(void) 174 | { 175 | (void)Py_InitModule("axolotl_curve25519", curve25519_functions); 176 | } 177 | 178 | #endif 179 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | from glob import glob 3 | from setuptools import setup,Extension 4 | 5 | sources = ['curve25519module.c', 'curve/curve25519-donna.c'] 6 | sources.extend(glob("curve/ed25519/*.c")) 7 | sources.extend(glob("curve/ed25519/additions/*.c")) 8 | sources.extend(glob("curve/ed25519/nacl_sha512/*.c")) 9 | #headers = ['curve25519-donna.h'] 10 | module_curve = Extension('axolotl_curve25519', 11 | sources = sorted(sources), 12 | # headers = headers, 13 | include_dirs = [ 14 | 'curve/ed25519/nacl_includes', 15 | 'curve/ed25519/additions', 16 | 'curve/ed25519' 17 | ] 18 | ) 19 | setup( 20 | name='python-axolotl-curve25519', 21 | version="0.4.1-2", 22 | license='GPLv3 License', 23 | author='Tarek Galal', 24 | ext_modules = [module_curve], 25 | author_email='tare2.galal@gmail.com', 26 | description='curve25519 with ed25519 signatures, used by libaxolotl', 27 | platforms='any' 28 | ) 29 | --------------------------------------------------------------------------------