Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 52 additions & 5 deletions src/crypto/crypto.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
#include "warnings.h"
#include "crypto.h"
#include "hash.h"
#include "blake2b.h"

#include "cryptonote_config.h"

Expand Down Expand Up @@ -608,7 +609,7 @@ namespace crypto {
return sc_isnonzero(&c2) == 0;
}

static void hash_to_ec(const public_key &key, ge_p3 &res) {
static void biased_hash_to_ec(const public_key &key, ge_p3 &res) {
hash h;
ge_p2 point;
ge_p1p1 point2;
Expand All @@ -618,11 +619,57 @@ namespace crypto {
ge_p1p1_to_p3(&res, &point2);
}

void crypto_ops::unbiased_hash_to_ec(const unsigned char *preimage, const std::size_t length, ec_point &res) {
uint8_t hash[64];
blake2b(std::addressof(hash), 64, preimage, length, NULL, 0);

ge_p2 first;
ge_fromfe_frombytes_vartime(&first, reinterpret_cast<const unsigned char *>(&hash));
ge_p1p1 first_p1p1;
ge_mul8(&first_p1p1, &first);
ge_p3 first_p3;
ge_p1p1_to_p3(&first_p3, &first_p1p1);

ge_p2 second;
ge_fromfe_frombytes_vartime(&second, reinterpret_cast<const unsigned char *>(&hash) + 32);
ge_p1p1 second_p1p1;
ge_mul8(&second_p1p1, &second);
ge_p3 second_p3;
ge_p1p1_to_p3(&second_p3, &second_p1p1);
ge_cached second_cached;
ge_p3_to_cached(&second_cached, &second_p3);

ge_p1p1 point;
ge_add(&point, &first_p3, &second_cached);

ge_p3 res_ge_p3;
ge_p1p1_to_p3(&res_ge_p3, &point);
ge_p3_tobytes(&res, &res_ge_p3);
}

static void biased_derive_key_image_generator(const public_key &pub, ec_point &ki_gen) {
ge_p3 point;
biased_hash_to_ec(pub, point);
ge_p3_tobytes(&ki_gen, &point);
}

static void unbiased_derive_key_image_generator(const public_key &pub, ec_point &ki_gen) {
unbiased_hash_to_ec(&pub, sizeof(public_key), ki_gen);
}

void crypto_ops::derive_key_image_generator(const public_key &pub, const bool biased, ec_point &ki_gen) {
if (biased)
biased_derive_key_image_generator(pub, ki_gen);
else
unbiased_derive_key_image_generator(pub, ki_gen);
}

// key image derivation used before FCMP++/Carrot
void crypto_ops::generate_key_image(const public_key &pub, const secret_key &sec, key_image &image) {
ge_p3 point;
ge_p2 point2;
assert(sc_check(&sec) == 0);
hash_to_ec(pub, point);
biased_hash_to_ec(pub, point);
ge_scalarmult(&point2, &unwrap(sec), &point);
ge_tobytes(&image, &point2);
}
Expand Down Expand Up @@ -683,7 +730,7 @@ POP_WARNINGS
random_scalar(k);
ge_scalarmult_base(&tmp3, &k);
ge_p3_tobytes(&buf->ab[i].a, &tmp3);
hash_to_ec(*pubs[i], tmp3);
biased_hash_to_ec(*pubs[i], tmp3);
ge_scalarmult(&tmp2, &k, &tmp3);
ge_tobytes(&buf->ab[i].b, &tmp2);
} else {
Expand All @@ -695,7 +742,7 @@ POP_WARNINGS
}
ge_double_scalarmult_base_vartime(&tmp2, &sig[i].c, &tmp3, &sig[i].r);
ge_tobytes(&buf->ab[i].a, &tmp2);
hash_to_ec(*pubs[i], tmp3);
biased_hash_to_ec(*pubs[i], tmp3);
ge_double_scalarmult_precomp_vartime(&tmp2, &sig[i].r, &tmp3, &sig[i].c, image_pre);
ge_tobytes(&buf->ab[i].b, &tmp2);
sc_add(&sum, &sum, &sig[i].c);
Expand Down Expand Up @@ -740,7 +787,7 @@ POP_WARNINGS
}
ge_double_scalarmult_base_vartime(&tmp2, &sig[i].c, &tmp3, &sig[i].r);
ge_tobytes(&buf->ab[i].a, &tmp2);
hash_to_ec(*pubs[i], tmp3);
biased_hash_to_ec(*pubs[i], tmp3);
ge_double_scalarmult_precomp_vartime(&tmp2, &sig[i].r, &tmp3, &sig[i].c, image_pre);
ge_tobytes(&buf->ab[i].b, &tmp2);
sc_add(&sum, &sum, &sig[i].c);
Expand Down
8 changes: 8 additions & 0 deletions src/crypto/crypto.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,10 @@ namespace crypto {
friend void generate_tx_proof_v1(const hash &, const public_key &, const public_key &, const boost::optional<public_key> &, const public_key &, const secret_key &, signature &);
static bool check_tx_proof(const hash &, const public_key &, const public_key &, const boost::optional<public_key> &, const public_key &, const signature &, const int);
friend bool check_tx_proof(const hash &, const public_key &, const public_key &, const boost::optional<public_key> &, const public_key &, const signature &, const int);
static void unbiased_hash_to_ec(const unsigned char *, const std::size_t, ec_point &);
friend void unbiased_hash_to_ec(const unsigned char *, const std::size_t, ec_point &);
static void derive_key_image_generator(const public_key &, const bool biased, ec_point &);
friend void derive_key_image_generator(const public_key &, const bool biased, ec_point &);
static void generate_key_image(const public_key &, const secret_key &, key_image &);
friend void generate_key_image(const public_key &, const secret_key &, key_image &);
static void generate_ring_signature(const hash &, const key_image &,
Expand Down Expand Up @@ -297,6 +301,10 @@ namespace crypto {
crypto_ops::derive_view_tag(derivation, output_index, vt);
}

inline void unbiased_hash_to_ec(const unsigned char *preimage, const std::size_t length, ec_point &res) {
crypto_ops::unbiased_hash_to_ec(preimage, length, res);
}

inline std::ostream &operator <<(std::ostream &o, const crypto::public_key &v) {
epee::to_hex::formatted(o, epee::as_byte_span(v)); return o;
}
Expand Down
2 changes: 1 addition & 1 deletion tests/crypto/crypto-tests.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ bool check_scalar(const crypto::ec_scalar &scalar);
void random_scalar(crypto::ec_scalar &res);
void hash_to_scalar(const void *data, std::size_t length, crypto::ec_scalar &res);
void hash_to_point(const crypto::hash &h, crypto::ec_point &res);
void hash_to_ec(const crypto::public_key &key, crypto::ec_point &res);
void biased_hash_to_ec(const crypto::public_key &key, crypto::ec_point &res);
bool check_ge_p3_identity_failure(const crypto::public_key &point);
bool check_ge_p3_identity_success(const crypto::public_key &point);
#endif
4 changes: 2 additions & 2 deletions tests/crypto/crypto.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,9 @@ void hash_to_point(const crypto::hash &h, crypto::ec_point &res) {
crypto::ge_tobytes(crypto::operator &(res), &point);
}

void hash_to_ec(const crypto::public_key &key, crypto::ec_point &res) {
void biased_hash_to_ec(const crypto::public_key &key, crypto::ec_point &res) {
crypto::ge_p3 tmp;
crypto::hash_to_ec(key, tmp);
crypto::biased_hash_to_ec(key, tmp);
crypto::ge_p3_tobytes(crypto::operator &(res), &tmp);
}

Expand Down
4 changes: 2 additions & 2 deletions tests/crypto/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -194,11 +194,11 @@ int main(int argc, char *argv[]) {
if (expected != actual) {
goto error;
}
} else if (cmd == "hash_to_ec") {
} else if (cmd == "biased_hash_to_ec") {
public_key key;
ec_point expected, actual;
get(input, key, expected);
hash_to_ec(key, actual);
biased_hash_to_ec(key, actual);
if (expected != actual) {
goto error;
}
Expand Down
Loading