123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150 |
- /*
- Public domain by Andrew M. <liquidsun@gmail.com>
- Ed25519 reference implementation using Ed25519-donna
- */
- /* define ED25519_SUFFIX to have it appended to the end of each public function */
- #if !defined(ED25519_SUFFIX)
- #define ED25519_SUFFIX
- #endif
- #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)
- #include "ed25519-donna.h"
- #include "ed25519.h"
- #include "ed25519-randombytes.h"
- #include "ed25519-hash.h"
- /*
- Generates a (extsk[0..31]) and aExt (extsk[32..63])
- */
- DONNA_INLINE static void
- ed25519_extsk(hash_512bits extsk, const ed25519_secret_key sk) {
- ed25519_hash(extsk, sk, 32);
- 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) {
- ed25519_hash_context ctx;
- ed25519_hash_init(&ctx);
- ed25519_hash_update(&ctx, RS, 32);
- ed25519_hash_update(&ctx, pk, 32);
- ed25519_hash_update(&ctx, m, mlen);
- ed25519_hash_final(&ctx, hram);
- }
- void
- ED25519_FN(ed25519_publickey) (const ed25519_secret_key sk, ed25519_public_key pk) {
- bignum256modm a;
- ge25519 ALIGN(16) A;
- hash_512bits extsk;
- /* A = aB */
- ed25519_extsk(extsk, sk);
- expand256_modm(a, extsk, 32);
- ge25519_scalarmult_base_niels(&A, ge25519_niels_base_multiples, a);
- ge25519_pack(pk, &A);
- }
- 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;
- }
- #include "ed25519-donna-batchverify.h"
- /*
- Fast Curve25519 basepoint scalar multiplication
- */
- void
- ED25519_FN(curved25519_scalarmult_basepoint) (curved25519_key pk, const curved25519_key e) {
- curved25519_key ec;
- bignum256modm s;
- bignum25519 ALIGN(16) yplusz, zminusy;
- ge25519 ALIGN(16) p;
- size_t i;
- /* clamp */
- for (i = 0; i < 32; i++) ec[i] = e[i];
- ec[0] &= 248;
- ec[31] &= 127;
- ec[31] |= 64;
- expand_raw256_modm(s, ec);
- /* scalar * basepoint */
- ge25519_scalarmult_base_niels(&p, ge25519_niels_base_multiples, s);
- /* u = (y + z) / (z - y) */
- curve25519_add(yplusz, p.y, p.z);
- curve25519_sub(zminusy, p.z, p.y);
- curve25519_recip(zminusy, zminusy);
- curve25519_mul(yplusz, yplusz, zminusy);
- curve25519_contract(pk, yplusz);
- }
|