|
|
|
@ -4,11 +4,20 @@
|
|
|
|
|
Ed25519 reference implementation using Ed25519-donna
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* define ED25519_SUFFIX to have it appended to the end of each public function */
|
|
|
|
|
#ifdef ED25519_SUFFIX
|
|
|
|
|
#define ED25519_FN3(fn,suffix) fn##suffix
|
|
|
|
|
#define ED25519_FN2(fn,suffix) ED25519_FN3(fn,suffix)
|
|
|
|
|
#define ED25519_FN(fn) ED25519_FN2(fn,ED25519_SUFFIX)
|
|
|
|
|
#else
|
|
|
|
|
#define ED25519_FN(fn) fn
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#include "ed25519-donna.h"
|
|
|
|
|
#include "ed25519.h"
|
|
|
|
|
#include "ed25519-hash-custom.h"
|
|
|
|
|
|
|
|
|
|
#include "curve25519-donna-scalarmult-base.h"
|
|
|
|
|
#include "ed25519-hash-custom.h"
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
Generates a (extsk[0..31]) and aExt (extsk[32..63])
|
|
|
|
@ -32,7 +41,7 @@ ed25519_hram(hash_512bits hram, const ed25519_signature RS, const ed25519_public
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
ed25519_publickey(const ed25519_secret_key sk, ed25519_public_key pk) {
|
|
|
|
|
ED25519_FN(ed25519_publickey) (const ed25519_secret_key sk, ed25519_public_key pk) {
|
|
|
|
|
bignum256modm a;
|
|
|
|
|
ge25519 ALIGN(16) A;
|
|
|
|
|
hash_512bits extsk;
|
|
|
|
@ -44,53 +53,8 @@ ed25519_publickey(const ed25519_secret_key sk, ed25519_public_key pk) {
|
|
|
|
|
ge25519_pack(pk, &A);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
ed25519_cosi_combine_publickeys(ed25519_public_key res, CONST ed25519_public_key *pks, size_t n) {
|
|
|
|
|
size_t i = 0;
|
|
|
|
|
ge25519 P;
|
|
|
|
|
ge25519_pniels sump;
|
|
|
|
|
ge25519_p1p1 sump1;
|
|
|
|
|
|
|
|
|
|
if (n == 1) {
|
|
|
|
|
memcpy(res, pks, sizeof(ed25519_public_key));
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
if (!ge25519_unpack_negative_vartime(&P, pks[i++])) {
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
ge25519_full_to_pniels(&sump, &P);
|
|
|
|
|
while (i < n - 1) {
|
|
|
|
|
if (!ge25519_unpack_negative_vartime(&P, pks[i++])) {
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
ge25519_pnielsadd(&sump, &P, &sump);
|
|
|
|
|
}
|
|
|
|
|
if (!ge25519_unpack_negative_vartime(&P, pks[i++])) {
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
ge25519_pnielsadd_p1p1(&sump1, &P, &sump, 0);
|
|
|
|
|
ge25519_p1p1_to_partial(&P, &sump1);
|
|
|
|
|
curve25519_neg(P.x, P.x);
|
|
|
|
|
ge25519_pack(res, &P);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
ed25519_cosi_combine_signatures(ed25519_signature res, const ed25519_public_key R, CONST ed25519_cosi_signature *sigs, size_t n) {
|
|
|
|
|
bignum256modm s, t;
|
|
|
|
|
size_t i = 0;
|
|
|
|
|
|
|
|
|
|
expand256_modm(s, sigs[i++], 32);
|
|
|
|
|
while (i < n) {
|
|
|
|
|
expand256_modm(t, sigs[i++], 32);
|
|
|
|
|
add256_modm(s, s, t);
|
|
|
|
|
}
|
|
|
|
|
memcpy(res, R, 32);
|
|
|
|
|
contract256_modm(res + 32, s);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
ed25519_cosi_sign(const unsigned char *m, size_t mlen, const ed25519_secret_key sk, const ed25519_secret_key nonce, const ed25519_public_key R, const ed25519_public_key pk, ed25519_cosi_signature sig) {
|
|
|
|
|
ED25519_FN(ed25519_cosi_sign) (const unsigned char *m, size_t mlen, const ed25519_secret_key sk, const ed25519_secret_key nonce, const ed25519_public_key R, const ed25519_public_key pk, ed25519_cosi_signature sig) {
|
|
|
|
|
bignum256modm r, S, a;
|
|
|
|
|
hash_512bits extsk, extnonce, hram;
|
|
|
|
|
|
|
|
|
@ -116,7 +80,7 @@ ed25519_cosi_sign(const unsigned char *m, size_t mlen, const ed25519_secret_key
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
ed25519_sign(const unsigned char *m, size_t mlen, const ed25519_secret_key sk, const ed25519_public_key pk, ed25519_signature RS) {
|
|
|
|
|
ED25519_FN(ed25519_sign) (const unsigned char *m, size_t mlen, const ed25519_secret_key sk, const ed25519_public_key pk, ed25519_signature RS) {
|
|
|
|
|
ed25519_hash_context ctx;
|
|
|
|
|
bignum256modm r, S, a;
|
|
|
|
|
ge25519 ALIGN(16) R;
|
|
|
|
@ -151,7 +115,7 @@ ed25519_sign(const unsigned char *m, size_t mlen, const ed25519_secret_key sk, c
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
ed25519_sign_open(const unsigned char *m, size_t mlen, const ed25519_public_key pk, const ed25519_signature RS) {
|
|
|
|
|
ED25519_FN(ed25519_sign_open) (const unsigned char *m, size_t mlen, const ed25519_public_key pk, const ed25519_signature RS) {
|
|
|
|
|
ge25519 ALIGN(16) R, A;
|
|
|
|
|
hash_512bits hash;
|
|
|
|
|
bignum256modm hram, S;
|
|
|
|
@ -175,6 +139,55 @@ ed25519_sign_open(const unsigned char *m, size_t mlen, const ed25519_public_key
|
|
|
|
|
return ed25519_verify(RS, checkR, 32) ? 0 : -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifndef ED25519_SUFFIX
|
|
|
|
|
|
|
|
|
|
#include "curve25519-donna-scalarmult-base.h"
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
ed25519_cosi_combine_publickeys(ed25519_public_key res, CONST ed25519_public_key *pks, size_t n) {
|
|
|
|
|
size_t i = 0;
|
|
|
|
|
ge25519 P;
|
|
|
|
|
ge25519_pniels sump;
|
|
|
|
|
ge25519_p1p1 sump1;
|
|
|
|
|
|
|
|
|
|
if (n == 1) {
|
|
|
|
|
memcpy(res, pks, sizeof(ed25519_public_key));
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
if (!ge25519_unpack_negative_vartime(&P, pks[i++])) {
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
ge25519_full_to_pniels(&sump, &P);
|
|
|
|
|
while (i < n - 1) {
|
|
|
|
|
if (!ge25519_unpack_negative_vartime(&P, pks[i++])) {
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
ge25519_pnielsadd(&sump, &P, &sump);
|
|
|
|
|
}
|
|
|
|
|
if (!ge25519_unpack_negative_vartime(&P, pks[i++])) {
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
ge25519_pnielsadd_p1p1(&sump1, &P, &sump, 0);
|
|
|
|
|
ge25519_p1p1_to_partial(&P, &sump1);
|
|
|
|
|
curve25519_neg(P.x, P.x);
|
|
|
|
|
ge25519_pack(res, &P);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
ed25519_cosi_combine_signatures(ed25519_signature res, const ed25519_public_key R, CONST ed25519_cosi_signature *sigs, size_t n) {
|
|
|
|
|
bignum256modm s, t;
|
|
|
|
|
size_t i = 0;
|
|
|
|
|
|
|
|
|
|
expand256_modm(s, sigs[i++], 32);
|
|
|
|
|
while (i < n) {
|
|
|
|
|
expand256_modm(t, sigs[i++], 32);
|
|
|
|
|
add256_modm(s, s, t);
|
|
|
|
|
}
|
|
|
|
|
memcpy(res, R, 32);
|
|
|
|
|
contract256_modm(res + 32, s);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
Fast Curve25519 basepoint scalar multiplication
|
|
|
|
|
*/
|
|
|
|
@ -216,3 +229,5 @@ curve25519_scalarmult(curve25519_key mypublic, const curve25519_key secret, cons
|
|
|
|
|
e[31] |= 0x40;
|
|
|
|
|
curve25519_scalarmult_donna(mypublic, e, basepoint);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endif // ED25519_SUFFIX
|
|
|
|
|