Home | History | Annotate | Line # | Download | only in ref10
      1 
      2 #include <string.h>
      3 
      4 #include "crypto_hash_sha512.h"
      5 #include "crypto_sign_ed25519.h"
      6 #include "sign_ed25519_ref10.h"
      7 #include "private/ed25519_ref10.h"
      8 #include "randombytes.h"
      9 #include "utils.h"
     10 
     11 void
     12 _crypto_sign_ed25519_ref10_hinit(crypto_hash_sha512_state *hs, int prehashed)
     13 {
     14     static const unsigned char DOM2PREFIX[32 + 2] = {
     15         'S', 'i', 'g', 'E', 'd', '2', '5', '5', '1', '9', ' ',
     16         'n', 'o', ' ',
     17         'E', 'd', '2', '5', '5', '1', '9', ' ',
     18         'c', 'o', 'l', 'l', 'i', 's', 'i', 'o', 'n', 's', 1, 0
     19     };
     20 
     21     crypto_hash_sha512_init(hs);
     22     if (prehashed) {
     23         crypto_hash_sha512_update(hs, DOM2PREFIX, sizeof DOM2PREFIX);
     24     }
     25 }
     26 
     27 static inline void
     28 _crypto_sign_ed25519_clamp(unsigned char k[32])
     29 {
     30     k[0] &= 248;
     31     k[31] &= 127;
     32     k[31] |= 64;
     33 }
     34 
     35 #ifdef ED25519_NONDETERMINISTIC
     36 /* r = hash(B || empty_labelset || Z || pad1 || k || pad2 || empty_labelset || K || extra || M) (mod q) */
     37 static void
     38 _crypto_sign_ed25519_synthetic_r_hv(crypto_hash_sha512_state *hs,
     39                                     unsigned char Z[32],
     40                                     const unsigned char sk[64])
     41 {
     42     static const unsigned char B[32] = {
     43         0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
     44         0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
     45         0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
     46         0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
     47     };
     48     static const unsigned char zeros[128] = { 0x00 };
     49     static const unsigned char empty_labelset[3] = { 0x02, 0x00, 0x00 };
     50 
     51     crypto_hash_sha512_update(hs, B, 32);
     52     crypto_hash_sha512_update(hs, empty_labelset, 3);
     53     randombytes_buf(Z, 32);
     54     crypto_hash_sha512_update(hs, Z, 32);
     55     crypto_hash_sha512_update(hs, zeros, 128 - (32 + 3 + 32) % 128);
     56     crypto_hash_sha512_update(hs, sk, 32);
     57     crypto_hash_sha512_update(hs, zeros, 128 - 32 % 128);
     58     crypto_hash_sha512_update(hs, empty_labelset, 3);
     59     crypto_hash_sha512_update(hs, sk + 32, 32);
     60     /* empty extra */
     61 }
     62 #endif
     63 
     64 int
     65 _crypto_sign_ed25519_detached(unsigned char *sig, unsigned long long *siglen_p,
     66                               const unsigned char *m, unsigned long long mlen,
     67                               const unsigned char *sk, int prehashed)
     68 {
     69     crypto_hash_sha512_state hs;
     70     unsigned char            az[64];
     71     unsigned char            nonce[64];
     72     unsigned char            hram[64];
     73     ge25519_p3               R;
     74 
     75     _crypto_sign_ed25519_ref10_hinit(&hs, prehashed);
     76 
     77 #ifdef ED25519_NONDETERMINISTIC
     78     memcpy(az, sk, 32);
     79     _crypto_sign_ed25519_synthetic_r_hv(&hs, nonce, az);
     80 #else
     81     crypto_hash_sha512(az, sk, 32);
     82     crypto_hash_sha512_update(&hs, az + 32, 32);
     83 #endif
     84 
     85     crypto_hash_sha512_update(&hs, m, mlen);
     86     crypto_hash_sha512_final(&hs, nonce);
     87 
     88     memmove(sig + 32, sk + 32, 32);
     89 
     90     sc25519_reduce(nonce);
     91     ge25519_scalarmult_base(&R, nonce);
     92     ge25519_p3_tobytes(sig, &R);
     93 
     94     _crypto_sign_ed25519_ref10_hinit(&hs, prehashed);
     95     crypto_hash_sha512_update(&hs, sig, 64);
     96     crypto_hash_sha512_update(&hs, m, mlen);
     97     crypto_hash_sha512_final(&hs, hram);
     98 
     99     sc25519_reduce(hram);
    100     _crypto_sign_ed25519_clamp(az);
    101     sc25519_muladd(sig + 32, hram, az, nonce);
    102 
    103     sodium_memzero(az, sizeof az);
    104     sodium_memzero(nonce, sizeof nonce);
    105 
    106     if (siglen_p != NULL) {
    107         *siglen_p = 64U;
    108     }
    109     return 0;
    110 }
    111 
    112 int
    113 crypto_sign_ed25519_detached(unsigned char *sig, unsigned long long *siglen_p,
    114                              const unsigned char *m, unsigned long long mlen,
    115                              const unsigned char *sk)
    116 {
    117     return _crypto_sign_ed25519_detached(sig, siglen_p, m, mlen, sk, 0);
    118 }
    119 
    120 int
    121 crypto_sign_ed25519(unsigned char *sm, unsigned long long *smlen_p,
    122                     const unsigned char *m, unsigned long long mlen,
    123                     const unsigned char *sk)
    124 {
    125     unsigned long long siglen;
    126 
    127     memmove(sm + crypto_sign_ed25519_BYTES, m, mlen);
    128     /* LCOV_EXCL_START */
    129     if (crypto_sign_ed25519_detached(
    130             sm, &siglen, sm + crypto_sign_ed25519_BYTES, mlen, sk) != 0 ||
    131         siglen != crypto_sign_ed25519_BYTES) {
    132         if (smlen_p != NULL) {
    133             *smlen_p = 0;
    134         }
    135         memset(sm, 0, mlen + crypto_sign_ed25519_BYTES);
    136         return -1;
    137     }
    138     /* LCOV_EXCL_STOP */
    139 
    140     if (smlen_p != NULL) {
    141         *smlen_p = mlen + siglen;
    142     }
    143     return 0;
    144 }
    145