tor

The Tor anonymity network
git clone https://git.dasho.dev/tor.git
Log | Files | Refs | README | LICENSE

ed25519.c (3687B)


      1 /*
      2 Public domain by Andrew M. <liquidsun@gmail.com>
      3 
      4 Ed25519 reference implementation using Ed25519-donna
      5 */
      6 
      7 
      8 /* define ED25519_SUFFIX to have it appended to the end of each public function */
      9 #if !defined(ED25519_SUFFIX)
     10 #define ED25519_SUFFIX 
     11 #endif
     12 
     13 #define ED25519_FN3(fn,suffix) fn##suffix
     14 #define ED25519_FN2(fn,suffix) ED25519_FN3(fn,suffix)
     15 #define ED25519_FN(fn)         ED25519_FN2(fn,ED25519_SUFFIX)
     16 
     17 #include "ed25519-donna.h"
     18 #include "ed25519.h"
     19 #include "ed25519-randombytes.h"
     20 #include "ed25519-hash.h"
     21 
     22 /*
     23 Generates a (extsk[0..31]) and aExt (extsk[32..63])
     24 */
     25 
     26 DONNA_INLINE static void
     27 ed25519_extsk(hash_512bits extsk, const ed25519_secret_key sk) {
     28 ed25519_hash(extsk, sk, 32);
     29 extsk[0] &= 248;
     30 extsk[31] &= 127;
     31 extsk[31] |= 64;
     32 }
     33 
     34 static void
     35 ed25519_hram(hash_512bits hram, const ed25519_signature RS, const ed25519_public_key pk, const unsigned char *m, size_t mlen) {
     36 ed25519_hash_context ctx;
     37 ed25519_hash_init(&ctx);
     38 ed25519_hash_update(&ctx, RS, 32);
     39 ed25519_hash_update(&ctx, pk, 32);
     40 ed25519_hash_update(&ctx, m, mlen);
     41 ed25519_hash_final(&ctx, hram);
     42 }
     43 
     44 void
     45 ED25519_FN(ed25519_publickey) (const ed25519_secret_key sk, ed25519_public_key pk) {
     46 bignum256modm a;
     47 ge25519 ALIGN(16) A;
     48 hash_512bits extsk;
     49 
     50 /* A = aB */
     51 ed25519_extsk(extsk, sk);
     52 expand256_modm(a, extsk, 32);
     53 ge25519_scalarmult_base_niels(&A, ge25519_niels_base_multiples, a);
     54 ge25519_pack(pk, &A);
     55 }
     56 
     57 
     58 void
     59 ED25519_FN(ed25519_sign) (const unsigned char *m, size_t mlen, const ed25519_secret_key sk, const ed25519_public_key pk, ed25519_signature RS) {
     60 ed25519_hash_context ctx;
     61 bignum256modm r, S, a;
     62 ge25519 ALIGN(16) R;
     63 hash_512bits extsk, hashr, hram;
     64 
     65 ed25519_extsk(extsk, sk);
     66 
     67 /* r = H(aExt[32..64], m) */
     68 ed25519_hash_init(&ctx);
     69 ed25519_hash_update(&ctx, extsk + 32, 32);
     70 ed25519_hash_update(&ctx, m, mlen);
     71 ed25519_hash_final(&ctx, hashr);
     72 expand256_modm(r, hashr, 64);
     73 
     74 /* R = rB */
     75 ge25519_scalarmult_base_niels(&R, ge25519_niels_base_multiples, r);
     76 ge25519_pack(RS, &R);
     77 
     78 /* S = H(R,A,m).. */
     79 ed25519_hram(hram, RS, pk, m, mlen);
     80 expand256_modm(S, hram, 64);
     81 
     82 /* S = H(R,A,m)a */
     83 expand256_modm(a, extsk, 32);
     84 mul256_modm(S, S, a);
     85 
     86 /* S = (r + H(R,A,m)a) */
     87 add256_modm(S, S, r);
     88 
     89 /* S = (r + H(R,A,m)a) mod L */	
     90 contract256_modm(RS + 32, S);
     91 }
     92 
     93 int
     94 ED25519_FN(ed25519_sign_open) (const unsigned char *m, size_t mlen, const ed25519_public_key pk, const ed25519_signature RS) {
     95 ge25519 ALIGN(16) R, A;
     96 hash_512bits hash;
     97 bignum256modm hram, S;
     98 unsigned char checkR[32];
     99 
    100 if ((RS[63] & 224) || !ge25519_unpack_negative_vartime(&A, pk))
    101 	return -1;
    102 
    103 /* hram = H(R,A,m) */
    104 ed25519_hram(hash, RS, pk, m, mlen);
    105 expand256_modm(hram, hash, 64);
    106 
    107 /* S */
    108 expand256_modm(S, RS + 32, 32);
    109 
    110 /* SB - H(R,A,m)A */
    111 ge25519_double_scalarmult_vartime(&R, &A, hram, S);
    112 ge25519_pack(checkR, &R);
    113 
    114 /* check that R = SB - H(R,A,m)A */
    115 return ed25519_verify(RS, checkR, 32) ? 0 : -1;
    116 }
    117 
    118 #include "ed25519-donna-batchverify.h"
    119 
    120 /*
    121 Fast Curve25519 basepoint scalar multiplication
    122 */
    123 
    124 void
    125 ED25519_FN(curved25519_scalarmult_basepoint) (curved25519_key pk, const curved25519_key e) {
    126 curved25519_key ec;
    127 bignum256modm s;
    128 bignum25519 ALIGN(16) yplusz, zminusy;
    129 ge25519 ALIGN(16) p;
    130 size_t i;
    131 
    132 /* clamp */
    133 for (i = 0; i < 32; i++) ec[i] = e[i];
    134 ec[0] &= 248;
    135 ec[31] &= 127;
    136 ec[31] |= 64;
    137 
    138 expand_raw256_modm(s, ec);
    139 
    140 /* scalar * basepoint */
    141 ge25519_scalarmult_base_niels(&p, ge25519_niels_base_multiples, s);
    142 
    143 /* u = (y + z) / (z - y) */
    144 curve25519_add(yplusz, p.y, p.z);
    145 curve25519_sub(zminusy, p.z, p.y);
    146 curve25519_recip(zminusy, zminusy);
    147 curve25519_mul(yplusz, yplusz, zminusy);
    148 curve25519_contract(pk, yplusz);
    149 }