bool crypto_ops::generate_key_derivation(const public_key &key1, const secret_key &key2, key_derivation &derivation) { ge_p3 point; ge_p2 point2; ge_p1p1 point3; assert(sc_check(&key2) == 0); if (ge_frombytes_vartime(&point, &key1) != 0) { return false; } ge_scalarmult(&point2, &key2, &point); ge_mul8(&point3, &point2); ge_p1p1_to_p2(&point2, &point3); ge_tobytes(&derivation, &point2); return true; }
int crypto_sign_edwards25519sha512batch_open(unsigned char *m, unsigned long long *mlen_p, const unsigned char *sm, unsigned long long smlen, const unsigned char *pk) { unsigned char h[64]; unsigned char t1[32], t2[32]; unsigned long long mlen; ge_cached Ai; ge_p1p1 csa; ge_p2 cs; ge_p3 A; ge_p3 R; ge_p3 cs3; *mlen_p = 0; if (smlen < 64 || smlen > SIZE_MAX) { return -1; } mlen = smlen - 64; if (sm[smlen - 1] & 224) { return -1; } if (ge_frombytes_negate_vartime(&A, pk) != 0 || ge_frombytes_negate_vartime(&R, sm) != 0) { return -1; } ge_p3_to_cached(&Ai, &A); crypto_hash_sha512(h, sm, mlen + 32); sc_reduce(h); ge_scalarmult_vartime(&cs3, h, &R); ge_add(&csa, &cs3, &Ai); ge_p1p1_to_p2(&cs, &csa); ge_tobytes(t1, &cs); t1[31] ^= 1 << 7; ge_scalarmult_base(&R, sm + 32 + mlen); ge_p3_tobytes(t2, &R); if (crypto_verify_32(t1, t2) != 0) { return -1; } *mlen_p = mlen; memmove(m, sm + 32, mlen); return 0; }
bool crypto_ops::derive_public_key(const key_derivation &derivation, size_t output_index, const public_key &base, public_key &derived_key) { ec_scalar scalar; ge_p3 point1; ge_p3 point2; ge_cached point3; ge_p1p1 point4; ge_p2 point5; if (ge_frombytes_vartime(&point1, &base) != 0) { return false; } derivation_to_scalar(derivation, output_index, scalar); ge_scalarmult_base(&point2, &scalar); ge_p3_to_cached(&point3, &point2); ge_add(&point4, &point1, &point3); ge_p1p1_to_p2(&point5, &point4); ge_tobytes(&derived_key, &point5); return true; }