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