int ed25519_donna_blind_public_key(unsigned char *out, const unsigned char *inp, const unsigned char *param) { static const bignum256modm zero = { 0 }; unsigned char tweak[64]; unsigned char pkcopy[32]; ge25519 ALIGN(16) A, Aprime; bignum256modm ALIGN(16) t; ed25519_donna_gettweak(tweak, param); expand256_modm(t, tweak, 32); /* No "ge25519_unpack", negate the public key. */ memcpy(pkcopy, inp, 32); pkcopy[31] ^= (1<<7); ge25519_unpack_negative_vartime(&A, pkcopy); /* A' = [tweak] * A + [0] * basepoint. */ ge25519_double_scalarmult_vartime(&Aprime, &A, t, zero); ge25519_pack(out, &Aprime); memwipe(tweak, 0, sizeof(tweak)); memwipe(pkcopy, 0, sizeof(pkcopy)); memwipe(&A, 0, sizeof(A)); memwipe(&Aprime, 0, sizeof(Aprime)); memwipe(t, 0, sizeof(t)); return 0; }
/* Do the scalar multiplication of <b>pubkey</b> with the group order * <b>modm_m</b>. Place the result in <b>out</b> which must be at least 32 * bytes long. */ int ed25519_donna_scalarmult_with_group_order(unsigned char *out, const unsigned char *pubkey) { static const bignum256modm ALIGN(16) zero = { 0 }; unsigned char pkcopy[32]; ge25519 ALIGN(16) Point, Result; /* No "ge25519_unpack", negate the public key and unpack it back. * See ed25519_donna_blind_public_key() */ memcpy(pkcopy, pubkey, 32); pkcopy[31] ^= (1<<7); if (!ge25519_unpack_negative_vartime(&Point, pkcopy)) { return -1; /* error: bail out */ } /* There is no regular scalarmult function so we have to do: * Result = l*P + 0*B */ ge25519_double_scalarmult_vartime(&Result, &Point, modm_m, zero); ge25519_pack(out, &Result); return 0; }
int ED25519_FN(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; }