1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
|
#include <string.h>
#include "api.h"
#include "crypto_hash_sha512.h"
#include "ge.h"
#include "sc.h"
#include "utils.h"
int
crypto_sign_detached(unsigned char *sig, unsigned long long *siglen_p,
const unsigned char *m, unsigned long long mlen,
const unsigned char *sk)
{
crypto_hash_sha512_state hs;
unsigned char pk[32];
unsigned char az[64];
unsigned char nonce[64];
unsigned char hram[64];
ge_p3 R;
memmove(pk, sk + 32, 32);
crypto_hash_sha512(az, sk, 32);
az[0] &= 248;
az[31] &= 63;
az[31] |= 64;
crypto_hash_sha512_init(&hs);
crypto_hash_sha512_update(&hs, az + 32, 32);
crypto_hash_sha512_update(&hs, m, mlen);
crypto_hash_sha512_final(&hs, nonce);
memmove(sig + 32, pk, 32);
sc_reduce(nonce);
ge_scalarmult_base(&R, nonce);
ge_p3_tobytes(sig, &R);
crypto_hash_sha512_init(&hs);
crypto_hash_sha512_update(&hs, sig, 64);
crypto_hash_sha512_update(&hs, m, mlen);
crypto_hash_sha512_final(&hs, hram);
sc_reduce(hram);
sc_muladd(sig + 32, hram, az, nonce);
sodium_memzero(az, sizeof az);
sodium_memzero(nonce, sizeof nonce);
if (siglen_p != NULL) {
*siglen_p = 64U;
}
return 0;
}
int
crypto_sign(unsigned char *sm, unsigned long long *smlen_p,
const unsigned char *m, unsigned long long mlen,
const unsigned char *sk)
{
unsigned long long siglen;
memmove(sm + crypto_sign_ed25519_BYTES, m, mlen);
/* LCOV_EXCL_START */
if (crypto_sign_detached(sm, &siglen, sm + crypto_sign_ed25519_BYTES,
mlen, sk) != 0 ||
siglen != crypto_sign_ed25519_BYTES) {
if (smlen_p != NULL) {
*smlen_p = 0;
}
memset(sm, 0, mlen + crypto_sign_ed25519_BYTES);
return -1;
}
/* LCOV_EXCL_STOP */
if (smlen_p != NULL) {
*smlen_p = mlen + siglen;
}
return 0;
}
|