forked from floodyberry/ed25519-donna
-
Notifications
You must be signed in to change notification settings - Fork 0
/
ed25519.c
109 lines (85 loc) · 2.45 KB
/
ed25519.c
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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
/*
Public domain by Andrew M. <liquidsun@gmail.com>
Ed25519 reference implementation using Ed25519-donna
*/
#include "ed25519-donna.h"
#include "ed25519.h"
#include "ed25519-randombytes.h"
#include <openssl/sha.h>
/*
Generates a (extsk[0..31]) and aExt (extsk[32..63])
*/
static void DONNA_INLINE
ed25519_extsk(hash_512bits extsk, const ed25519_secret_key sk) {
SHA512(sk, 32, extsk);
extsk[0] &= 248;
extsk[31] &= 127;
extsk[31] |= 64;
}
static void
ed25519_hram(hash_512bits hram, const ed25519_signature RS, const ed25519_public_key pk, const unsigned char *m, size_t mlen) {
SHA512_CTX shactx;
SHA512_Init(&shactx);
SHA512_Update(&shactx, RS, 32);
SHA512_Update(&shactx, pk, 32);
SHA512_Update(&shactx, m, mlen);
SHA512_Final(hram, &shactx);
}
void
ed25519_publickey(const ed25519_secret_key sk, ed25519_public_key pk) {
bignum256modm a;
ge25519 MM16 A;
hash_512bits extsk;
/* A = aB */
ed25519_extsk(extsk, sk);
expand256_modm(a, extsk, 32);
ge25519_scalarmult_base_niels(&A, a);
ge25519_pack(pk, &A);
}
void
ed25519_sign(const unsigned char *m, size_t mlen, const ed25519_secret_key sk, const ed25519_public_key pk, ed25519_signature RS) {
SHA512_CTX shactx;
bignum256modm r, S, a;
ge25519 MM16 R;
hash_512bits extsk, hashr, hram;
ed25519_extsk(extsk, sk);
/* r = H(aExt[32..64], m) */
SHA512_Init(&shactx);
SHA512_Update(&shactx, extsk + 32, 32);
SHA512_Update(&shactx, m, mlen);
SHA512_Final(hashr, &shactx);
expand256_modm(r, hashr, 64);
/* R = rB */
ge25519_scalarmult_base_niels(&R, r);
ge25519_pack(RS, &R);
/* S = H(R,A,m).. */
ed25519_hram(hram, RS, pk, m, mlen);
expand256_modm(S, hram, 64);
/* S = H(R,A,m)a */
expand256_modm(a, extsk, 32);
mul256_modm(S, S, a);
/* S = (r + H(R,A,m)a) */
add256_modm(S, S, r);
/* S = (r + H(R,A,m)a) mod L */
contract256_modm(RS + 32, S);
}
int
ed25519_sign_open(const unsigned char *m, size_t mlen, const ed25519_public_key pk, const ed25519_signature RS) {
ge25519 MM16 R, A;
hash_512bits hash;
bignum256modm hram, S;
unsigned char checkR[32];
if ((RS[63] & 224) || !ge25519_unpack_negative_vartime(&A, pk))
return -1;
/* hram = H(R,A,m) */
ed25519_hram(hash, RS, pk, m, mlen);
expand256_modm(hram, hash, 64);
/* S */
expand256_modm(S, RS + 32, 32);
/* SB - H(R,A,m)A */
ge25519_double_scalarmult_vartime(&R, &A, hram, S);
ge25519_pack(checkR, &R);
/* check that R = SB - H(R,A,m)A */
return ed25519_verify(RS, checkR, 32) ? 0 : -1;
}
#include "ed25519-donna-batchverify.h"