1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-11-22 07:28:10 +00:00

ed25519-donna: Add ED25519_SUFFIX

This commit is contained in:
Saleem Rashid 2017-05-16 19:19:58 +01:00 committed by Pavol Rusnak
parent 406c926caa
commit 36e8ef48f1
No known key found for this signature in database
GPG Key ID: 91F3B339B9A02A3D
4 changed files with 118 additions and 92 deletions

View File

@ -96,9 +96,11 @@ curve25519_sub(bignum25519 out, const bignum25519 a, const bignum25519 b) {
out[9] = twoP13579 + a[9] - b[9] ;
}
DONNA_INLINE DONNA_UNUSED static void
curve25519_scalar_product(bignum25519 out, const bignum25519 in, const uint32_t scalar);
/* out = in * scalar */
DONNA_INLINE static void
curve25519_scalar_product(bignum25519 out, const bignum25519 in, const uint32_t scalar) {
void curve25519_scalar_product(bignum25519 out, const bignum25519 in, const uint32_t scalar) {
uint64_t a;
uint32_t c;
a = mul32x32_64(in[0], scalar); out[0] = (uint32_t)a & reduce_mask_26; c = (uint32_t)(a >> 26);

View File

@ -4,6 +4,12 @@
#include <string.h>
#include <stdint.h>
#ifdef __GNUC__
#define DONNA_UNUSED __attribute__((unused))
#else
#define DONNA_UNUSED
#endif
#define DONNA_INLINE
#undef ALIGN
#define ALIGN(x) __attribute__((aligned(x)))

View File

@ -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,6 +53,96 @@ ed25519_publickey(const ed25519_secret_key sk, ed25519_public_key pk) {
ge25519_pack(pk, &A);
}
void
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;
ed25519_extsk(extsk, sk);
ed25519_extsk(extnonce, nonce);
/* r = nonce */
expand256_modm(r, extnonce, 32);
/* S = H(R,A,m).. */
ed25519_hram(hram, R, 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(sig, S);
}
void
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;
hash_512bits extsk, hashr, hram;
ed25519_extsk(extsk, sk);
/* r = H(aExt[32..64], m) */
ed25519_hash_init(&ctx);
ed25519_hash_update(&ctx, extsk + 32, 32);
ed25519_hash_update(&ctx, m, mlen);
ed25519_hash_final(&ctx, hashr);
expand256_modm(r, hashr, 64);
/* R = rB */
ge25519_scalarmult_base_niels(&R, ge25519_niels_base_multiples, 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_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;
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;
}
#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;
@ -89,92 +188,6 @@ ed25519_cosi_combine_signatures(ed25519_signature res, const ed25519_public_key
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) {
bignum256modm r, S, a;
hash_512bits extsk, extnonce, hram;
ed25519_extsk(extsk, sk);
ed25519_extsk(extnonce, nonce);
/* r = nonce */
expand256_modm(r, extnonce, 32);
/* S = H(R,A,m).. */
ed25519_hram(hram, R, 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(sig, S);
}
void
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;
hash_512bits extsk, hashr, hram;
ed25519_extsk(extsk, sk);
/* r = H(aExt[32..64], m) */
ed25519_hash_init(&ctx);
ed25519_hash_update(&ctx, extsk + 32, 32);
ed25519_hash_update(&ctx, m, mlen);
ed25519_hash_final(&ctx, hashr);
expand256_modm(r, hashr, 64);
/* R = rB */
ge25519_scalarmult_base_niels(&R, ge25519_niels_base_multiples, 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 ALIGN(16) 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;
}
/*
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

View File

@ -254,7 +254,10 @@ static void expand256_modm(bignum256modm out, const unsigned char *in, size_t le
barrett_reduce256_modm(out, q1, out);
}
static void expand_raw256_modm(bignum256modm out, const unsigned char in[32]) {
DONNA_UNUSED static void
expand_raw256_modm(bignum256modm out, const unsigned char in[32]);
void expand_raw256_modm(bignum256modm out, const unsigned char in[32]) {
bignum256modm_element_t x[8];
x[0] = U8TO32_LE(in + 0);