diff --git a/src/blockchain_db/lmdb/db_lmdb.cpp b/src/blockchain_db/lmdb/db_lmdb.cpp index 561d2e3fd..af7de2ef3 100644 --- a/src/blockchain_db/lmdb/db_lmdb.cpp +++ b/src/blockchain_db/lmdb/db_lmdb.cpp @@ -6800,7 +6800,7 @@ void BlockchainLMDB::migrate_5_6() tuple_context = m_curve_trees->output_to_leaf_context( output_id, output_data.pubkey, - rct::rct2pk(output_data.commitment)); + output_data.commitment); } catch(...) { diff --git a/src/crypto/crypto-ops-data.c b/src/crypto/crypto-ops-data.c index edaa4644f..57304c41d 100644 --- a/src/crypto/crypto-ops-data.c +++ b/src/crypto/crypto-ops-data.c @@ -870,6 +870,7 @@ const fe fe_fffb1 = {-31702527, -2466483, -26106795, -12203692, -12169197, -3210 const fe fe_fffb2 = {8166131, -6741800, -17040804, 3154616, 21461005, 1466302, -30876704, -6368709, 10503587, -13363080}; /* sqrt(2 * A * (A + 2)) */ const fe fe_fffb3 = {-13620103, 14639558, 4532995, 7679154, 16815101, -15883539, -22863840, -14813421, 13716513, -6477756}; /* sqrt(-sqrt(-1) * A * (A + 2)) */ const fe fe_fffb4 = {-21786234, -12173074, 21573800, 4524538, -4645904, 16204591, 8012863, -8444712, 3212926, 6885324}; /* sqrt(sqrt(-1) * A * (A + 2)) */ +const fe fe_a_inv_3 = {-22207407, 11184811, 22369621, -11184811, -22369621, 11184811, 22369621, -11184811, -22369621, 11184811}; /* A / 3*/ const ge_p3 ge_p3_identity = { {0}, {1, 0}, {1, 0}, {0} }; const ge_p3 ge_p3_H = { {7329926, -15101362, 31411471, 7614783, 27996851, -3197071, -11157635, -6878293, 466949, -7986503}, diff --git a/src/crypto/crypto-ops.c b/src/crypto/crypto-ops.c index 314fe448a..edfc61c3c 100644 --- a/src/crypto/crypto-ops.c +++ b/src/crypto/crypto-ops.c @@ -1328,15 +1328,9 @@ void ge_double_scalarmult_base_vartime_p3(ge_p3 *r3, const unsigned char *a, con } } -/* From ge_frombytes.c, modified */ +/* From fe_frombytes.c */ -int ge_frombytes_vartime(ge_p3 *h, const unsigned char *s) { - fe u; - fe v; - fe vxx; - fe check; - - /* From fe_frombytes.c */ +int fe_y_frombytes_vartime(fe y, const unsigned char *s) { int64_t h0 = load_4(s); int64_t h1 = load_3(s + 4) << 6; @@ -1378,18 +1372,31 @@ int ge_frombytes_vartime(ge_p3 *h, const unsigned char *s) { carry6 = (h6 + (int64_t) (1<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26; carry8 = (h8 + (int64_t) (1<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26; - h->Y[0] = h0; - h->Y[1] = h1; - h->Y[2] = h2; - h->Y[3] = h3; - h->Y[4] = h4; - h->Y[5] = h5; - h->Y[6] = h6; - h->Y[7] = h7; - h->Y[8] = h8; - h->Y[9] = h9; + y[0] = h0; + y[1] = h1; + y[2] = h2; + y[3] = h3; + y[4] = h4; + y[5] = h5; + y[6] = h6; + y[7] = h7; + y[8] = h8; + y[9] = h9; - /* End fe_frombytes.c */ + return 0; +} + +/* From ge_frombytes.c, modified */ + +int ge_frombytes_vartime(ge_p3 *h, const unsigned char *s) { + fe u; + fe v; + fe vxx; + fe check; + + if (fe_y_frombytes_vartime(h->Y, s) != 0) { + return -1; + } fe_1(h->Z); fe_sq(u, h->Y); @@ -3877,3 +3884,27 @@ int ge_p3_is_point_at_infinity_vartime(const ge_p3 *p) { // Y/Z = 0/0 return 0; } + +// https://www.ietf.org/archive/id/draft-ietf-lwig-curve-representations-02.pdf E.2 +void fe_y_to_wei_x(unsigned char *wei_x, const fe y) +{ + fe one; + fe_1(one); + + // (1+y),(1-y) + fe one_plus_y; + fe_add(one_plus_y, one, y); + fe one_minus_y; + fe_sub(one_minus_y, one, y); + + // (1/(1-y))*(1+y) + fe inv_one_minus_y; + fe_invert(inv_one_minus_y, one_minus_y); + fe inv_one_minus_y_mul_one_plus_y; + fe_mul(inv_one_minus_y_mul_one_plus_y, inv_one_minus_y, one_plus_y); + + // wei x = (1/(1-y))*(1+y) + (A/3) + fe wei_x_fe; + fe_add(wei_x_fe, inv_one_minus_y_mul_one_plus_y, fe_a_inv_3); + fe_tobytes(wei_x, wei_x_fe); +} diff --git a/src/crypto/crypto-ops.h b/src/crypto/crypto-ops.h index c103f1f78..ff4ceaf60 100644 --- a/src/crypto/crypto-ops.h +++ b/src/crypto/crypto-ops.h @@ -88,6 +88,7 @@ void ge_double_scalarmult_base_vartime_p3(ge_p3 *, const unsigned char *, const extern const fe fe_sqrtm1; extern const fe fe_d; +int fe_y_frombytes_vartime(fe, const unsigned char *); int ge_frombytes_vartime(ge_p3 *, const unsigned char *); /* From ge_p1p1_to_p2.c */ @@ -143,6 +144,7 @@ extern const fe fe_fffb1; extern const fe fe_fffb2; extern const fe fe_fffb3; extern const fe fe_fffb4; +extern const fe fe_a_inv_3; extern const ge_p3 ge_p3_identity; extern const ge_p3 ge_p3_H; void ge_fromfe_frombytes_vartime(ge_p2 *, const unsigned char *); @@ -167,3 +169,5 @@ void fe_mul(fe out, const fe, const fe); void fe_0(fe h); int ge_p3_is_point_at_infinity_vartime(const ge_p3 *p); + +void fe_y_to_wei_x(unsigned char *wei_x, const fe y); diff --git a/src/fcmp/curve_trees.cpp b/src/fcmp/curve_trees.cpp index 837d2faa9..cb2b82f58 100644 --- a/src/fcmp/curve_trees.cpp +++ b/src/fcmp/curve_trees.cpp @@ -630,26 +630,14 @@ template<> LeafTupleContext CurveTrees::output_to_leaf_context( const std::uint64_t output_id, const crypto::public_key &output_pubkey, - const crypto::public_key &commitment) const + const rct::key &commitment) const { - if (!crypto::check_key(output_pubkey)) - throw std::runtime_error("invalid output pub key"); + rct::key O, C; - const auto clear_torsion = [](const crypto::public_key &key, const std::string &s) - { - // TODO: don't need to decompress and recompress points, can be optimized - rct::key torsion_cleared_key = rct::scalarmultKey(rct::pk2rct(key), rct::INV_EIGHT); - torsion_cleared_key = rct::scalarmult8(torsion_cleared_key); - - if (torsion_cleared_key == rct::I) - throw std::runtime_error(s + " cannot equal identity"); - - return torsion_cleared_key; - }; - - // Torsion clear the output pub key and commitment - rct::key O = clear_torsion(output_pubkey, "output pub key"); - rct::key C = clear_torsion(commitment, "commitment"); + if (!rct::clear_torsion(rct::pk2rct(output_pubkey), O)) + throw std::runtime_error("output pub key is invalid, failed to clear torsion"); + if (!rct::clear_torsion(commitment, C)) + throw std::runtime_error("commitment is invalid, failed to clear torsion"); PreprocessedLeafTuple o_c{ .O = std::move(O), @@ -666,16 +654,25 @@ template<> CurveTrees::LeafTuple CurveTrees::leaf_tuple( const PreprocessedLeafTuple &preprocessed_leaf_tuple) const { - const crypto::public_key &O = rct::rct2pk(preprocessed_leaf_tuple.O); - const crypto::public_key &C = rct::rct2pk(preprocessed_leaf_tuple.C); + const rct::key &O = preprocessed_leaf_tuple.O; + const rct::key &C = preprocessed_leaf_tuple.C; crypto::ec_point I; - crypto::derive_key_image_generator(O, I); + crypto::derive_key_image_generator(rct::rct2pk(O), I); + + rct::key O_x, I_x, C_x; + + if (!rct::point_to_wei_x(O, O_x)) + throw std::runtime_error("failed to get wei x scalar from O"); + if (!rct::point_to_wei_x(rct::pt2rct(I), I_x)) + throw std::runtime_error("failed to get wei x scalar from I"); + if (!rct::point_to_wei_x(C, C_x)) + throw std::runtime_error("failed to get wei x scalar from C"); return LeafTuple{ - .O_x = tower_cycle::ed_25519_point_to_scalar(O), - .I_x = tower_cycle::ed_25519_point_to_scalar(I), - .C_x = tower_cycle::ed_25519_point_to_scalar(C) + .O_x = tower_cycle::selene_scalar_from_bytes(O_x), + .I_x = tower_cycle::selene_scalar_from_bytes(I_x), + .C_x = tower_cycle::selene_scalar_from_bytes(C_x) }; }; //---------------------------------------------------------------------------------------------------------------------- @@ -732,7 +729,7 @@ void CurveTrees::tx_outs_to_leaf_tuple_contexts(const cryptonote // Convert output to leaf tuple context; throws if output is invalid leaf_tuple_context = output_to_leaf_context(output_ids[i], output_public_key, - rct::rct2pk(commitment)); + commitment); } catch (...) { diff --git a/src/fcmp/curve_trees.h b/src/fcmp/curve_trees.h index a337481e1..8f1270552 100644 --- a/src/fcmp/curve_trees.h +++ b/src/fcmp/curve_trees.h @@ -233,7 +233,7 @@ public: // Convert cryptonote output pub key and commitment to a leaf tuple for the curve trees tree LeafTupleContext output_to_leaf_context(const std::uint64_t output_id, const crypto::public_key &output_pubkey, - const crypto::public_key &C) const; + const rct::key &C) const; LeafTuple leaf_tuple(const PreprocessedLeafTuple &preprocessed_leaf_tuple) const; diff --git a/src/fcmp/fcmp_rust/Cargo.lock b/src/fcmp/fcmp_rust/Cargo.lock index 18edc208f..196a2a39d 100644 --- a/src/fcmp/fcmp_rust/Cargo.lock +++ b/src/fcmp/fcmp_rust/Cargo.lock @@ -71,7 +71,7 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "ciphersuite" version = "0.4.1" -source = "git+https://github.com/kayabaNerve/fcmp-plus-plus#506fe19c9ea0381a65a55eb846deacfdfcff5b2a" +source = "git+https://github.com/kayabaNerve/fcmp-plus-plus#529a3fe9c54b7f701d7978b3dc781ea27ba7d7e5" dependencies = [ "blake2", "dalek-ff-group", @@ -160,7 +160,7 @@ dependencies = [ [[package]] name = "dalek-ff-group" version = "0.4.1" -source = "git+https://github.com/kayabaNerve/fcmp-plus-plus#506fe19c9ea0381a65a55eb846deacfdfcff5b2a" +source = "git+https://github.com/kayabaNerve/fcmp-plus-plus#529a3fe9c54b7f701d7978b3dc781ea27ba7d7e5" dependencies = [ "crypto-bigint", "curve25519-dalek", @@ -197,7 +197,7 @@ dependencies = [ [[package]] name = "ec-divisors" version = "0.1.0" -source = "git+https://github.com/kayabaNerve/fcmp-plus-plus#506fe19c9ea0381a65a55eb846deacfdfcff5b2a" +source = "git+https://github.com/kayabaNerve/fcmp-plus-plus#529a3fe9c54b7f701d7978b3dc781ea27ba7d7e5" dependencies = [ "dalek-ff-group", "group", @@ -244,11 +244,10 @@ version = "0.0.0" dependencies = [ "ciphersuite", "ec-divisors", - "flexible-transcript", "full-chain-membership-proofs", "generalized-bulletproofs", "helioselene", - "rand_core", + "monero-fcmp-plus-plus", "std-shims", ] @@ -272,7 +271,7 @@ checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" [[package]] name = "flexible-transcript" version = "0.3.2" -source = "git+https://github.com/kayabaNerve/fcmp-plus-plus#506fe19c9ea0381a65a55eb846deacfdfcff5b2a" +source = "git+https://github.com/kayabaNerve/fcmp-plus-plus#529a3fe9c54b7f701d7978b3dc781ea27ba7d7e5" dependencies = [ "blake2", "digest", @@ -285,12 +284,15 @@ dependencies = [ [[package]] name = "full-chain-membership-proofs" version = "0.1.0" -source = "git+https://github.com/kayabaNerve/fcmp-plus-plus#506fe19c9ea0381a65a55eb846deacfdfcff5b2a" +source = "git+https://github.com/kayabaNerve/fcmp-plus-plus#529a3fe9c54b7f701d7978b3dc781ea27ba7d7e5" dependencies = [ + "blake2", "ciphersuite", "ec-divisors", - "flexible-transcript", "generalized-bulletproofs", + "generalized-bulletproofs-circuit-abstraction", + "generalized-bulletproofs-ec-gadgets", + "generic-array 1.1.0", "multiexp", "rand_core", "zeroize", @@ -305,12 +307,45 @@ checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" [[package]] name = "generalized-bulletproofs" version = "0.1.0" -source = "git+https://github.com/kayabaNerve/fcmp-plus-plus#506fe19c9ea0381a65a55eb846deacfdfcff5b2a" +source = "git+https://github.com/kayabaNerve/fcmp-plus-plus#529a3fe9c54b7f701d7978b3dc781ea27ba7d7e5" +dependencies = [ + "blake2", + "ciphersuite", + "multiexp", + "rand_core", + "zeroize", +] + +[[package]] +name = "generalized-bulletproofs-circuit-abstraction" +version = "0.1.0" +source = "git+https://github.com/kayabaNerve/fcmp-plus-plus#529a3fe9c54b7f701d7978b3dc781ea27ba7d7e5" +dependencies = [ + "ciphersuite", + "generalized-bulletproofs", + "zeroize", +] + +[[package]] +name = "generalized-bulletproofs-ec-gadgets" +version = "0.1.0" +source = "git+https://github.com/kayabaNerve/fcmp-plus-plus#529a3fe9c54b7f701d7978b3dc781ea27ba7d7e5" +dependencies = [ + "ciphersuite", + "generalized-bulletproofs-circuit-abstraction", + "generic-array 1.1.0", +] + +[[package]] +name = "generalized-schnorr" +version = "0.1.0" +source = "git+https://github.com/kayabaNerve/fcmp-plus-plus#529a3fe9c54b7f701d7978b3dc781ea27ba7d7e5" dependencies = [ "ciphersuite", "flexible-transcript", "multiexp", "rand_core", + "std-shims", "zeroize", ] @@ -368,7 +403,7 @@ dependencies = [ [[package]] name = "helioselene" version = "0.1.0" -source = "git+https://github.com/kayabaNerve/fcmp-plus-plus#506fe19c9ea0381a65a55eb846deacfdfcff5b2a" +source = "git+https://github.com/kayabaNerve/fcmp-plus-plus#529a3fe9c54b7f701d7978b3dc781ea27ba7d7e5" dependencies = [ "crypto-bigint", "dalek-ff-group", @@ -429,7 +464,7 @@ dependencies = [ [[package]] name = "minimal-ed448" version = "0.4.0" -source = "git+https://github.com/kayabaNerve/fcmp-plus-plus#506fe19c9ea0381a65a55eb846deacfdfcff5b2a" +source = "git+https://github.com/kayabaNerve/fcmp-plus-plus#529a3fe9c54b7f701d7978b3dc781ea27ba7d7e5" dependencies = [ "crypto-bigint", "ff", @@ -441,10 +476,69 @@ dependencies = [ "zeroize", ] +[[package]] +name = "monero-fcmp-plus-plus" +version = "0.1.0" +source = "git+https://github.com/kayabaNerve/fcmp-plus-plus#529a3fe9c54b7f701d7978b3dc781ea27ba7d7e5" +dependencies = [ + "ciphersuite", + "dalek-ff-group", + "ec-divisors", + "flexible-transcript", + "full-chain-membership-proofs", + "generalized-bulletproofs", + "generalized-bulletproofs-ec-gadgets", + "generalized-schnorr", + "generic-array 1.1.0", + "monero-generators", + "monero-io", + "monero-primitives", + "multiexp", + "rand_core", + "std-shims", + "zeroize", +] + +[[package]] +name = "monero-generators" +version = "0.4.0" +source = "git+https://github.com/kayabaNerve/fcmp-plus-plus#529a3fe9c54b7f701d7978b3dc781ea27ba7d7e5" +dependencies = [ + "curve25519-dalek", + "dalek-ff-group", + "group", + "monero-io", + "sha3", + "std-shims", + "subtle", +] + +[[package]] +name = "monero-io" +version = "0.1.0" +source = "git+https://github.com/kayabaNerve/fcmp-plus-plus#529a3fe9c54b7f701d7978b3dc781ea27ba7d7e5" +dependencies = [ + "curve25519-dalek", + "std-shims", +] + +[[package]] +name = "monero-primitives" +version = "0.1.0" +source = "git+https://github.com/kayabaNerve/fcmp-plus-plus#529a3fe9c54b7f701d7978b3dc781ea27ba7d7e5" +dependencies = [ + "curve25519-dalek", + "monero-generators", + "monero-io", + "sha3", + "std-shims", + "zeroize", +] + [[package]] name = "multiexp" version = "0.4.0" -source = "git+https://github.com/kayabaNerve/fcmp-plus-plus#506fe19c9ea0381a65a55eb846deacfdfcff5b2a" +source = "git+https://github.com/kayabaNerve/fcmp-plus-plus#529a3fe9c54b7f701d7978b3dc781ea27ba7d7e5" dependencies = [ "ff", "group", @@ -607,7 +701,7 @@ dependencies = [ [[package]] name = "std-shims" version = "0.1.1" -source = "git+https://github.com/kayabaNerve/fcmp-plus-plus#506fe19c9ea0381a65a55eb846deacfdfcff5b2a" +source = "git+https://github.com/kayabaNerve/fcmp-plus-plus#529a3fe9c54b7f701d7978b3dc781ea27ba7d7e5" dependencies = [ "hashbrown", "spin", @@ -621,9 +715,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" -version = "2.0.70" +version = "2.0.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f0209b68b3613b093e0ec905354eccaedcfe83b8cb37cbdeae64026c3064c16" +checksum = "dc4b9b9bf2add8093d3f2c0204471e951b2285580335de42f9d2534f3ae7a8af" dependencies = [ "proc-macro2", "quote", @@ -650,9 +744,9 @@ checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "version_check" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "wasi" diff --git a/src/fcmp/fcmp_rust/Cargo.toml b/src/fcmp/fcmp_rust/Cargo.toml index 871a6cb66..21573b824 100644 --- a/src/fcmp/fcmp_rust/Cargo.toml +++ b/src/fcmp/fcmp_rust/Cargo.toml @@ -10,9 +10,6 @@ crate-type = ["staticlib"] [dependencies] std-shims = { git = "https://github.com/kayabaNerve/fcmp-plus-plus" } -rand_core = { version = "0.6", features = ["getrandom"] } - -transcript = { package = "flexible-transcript", git = "https://github.com/kayabaNerve/fcmp-plus-plus", features = ["recommended"] } helioselene = { git = "https://github.com/kayabaNerve/fcmp-plus-plus" } ciphersuite = { git = "https://github.com/kayabaNerve/fcmp-plus-plus", features = ["ed25519", "helioselene"] } @@ -21,6 +18,8 @@ generalized-bulletproofs = { git = "https://github.com/kayabaNerve/fcmp-plus-plu ec-divisors = { git = "https://github.com/kayabaNerve/fcmp-plus-plus", features = ["ed25519"] } full-chain-membership-proofs = { git = "https://github.com/kayabaNerve/fcmp-plus-plus" } +monero-fcmp-plus-plus = { git = "https://github.com/kayabaNerve/fcmp-plus-plus" } + [patch.crates-io] crypto-bigint = { git = "https://github.com/kayabaNerve/crypto-bigint", branch = "c-repr" } diff --git a/src/fcmp/fcmp_rust/fcmp++.h b/src/fcmp/fcmp_rust/fcmp++.h index d222dd910..184737cd5 100644 --- a/src/fcmp/fcmp_rust/fcmp++.h +++ b/src/fcmp/fcmp_rust/fcmp++.h @@ -104,7 +104,7 @@ HeliosPoint helios_point_from_bytes(const uint8_t *helios_point_bytes); SelenePoint selene_point_from_bytes(const uint8_t *selene_point_bytes); -SeleneScalar ed25519_point_to_selene_scalar(const uint8_t *ed25519_point); +SeleneScalar selene_scalar_from_bytes(const uint8_t *selene_scalar_bytes); HeliosScalar selene_point_to_helios_scalar(SelenePoint selene_point); diff --git a/src/fcmp/fcmp_rust/src/lib.rs b/src/fcmp/fcmp_rust/src/lib.rs index 60197349f..cb256f14f 100644 --- a/src/fcmp/fcmp_rust/src/lib.rs +++ b/src/fcmp/fcmp_rust/src/lib.rs @@ -1,56 +1,29 @@ -use std_shims::sync::OnceLock; - -use rand_core::OsRng; - use ciphersuite::{ group::{ ff::{Field, PrimeField}, - Group, GroupEncoding, + GroupEncoding, }, - Ciphersuite, Ed25519, Helios, Selene, + Ciphersuite, Helios, Selene, }; use helioselene::{ Field25519 as SeleneScalar, HeliosPoint, HelioseleneField as HeliosScalar, SelenePoint, }; -use transcript::RecommendedTranscript; - -use generalized_bulletproofs::Generators; use ec_divisors::DivisorCurve; use full_chain_membership_proofs::tree::{hash_grow, hash_trim}; +use monero_fcmp_plus_plus::{HELIOS_HASH_INIT, SELENE_HASH_INIT, HELIOS_GENERATORS, SELENE_GENERATORS}; + // TODO: Use a macro to de-duplicate some of of this code -const HELIOS_GENERATORS_LENGTH: usize = 128; -const SELENE_GENERATORS_LENGTH: usize = 256; - -static HELIOS_GENERATORS: OnceLock> = OnceLock::new(); -static SELENE_GENERATORS: OnceLock> = OnceLock::new(); - -static HELIOS_HASH_INIT: OnceLock = OnceLock::new(); -static SELENE_HASH_INIT: OnceLock = OnceLock::new(); - -// TODO: Don't use random generators -fn helios_generators() -> &'static Generators { - HELIOS_GENERATORS.get_or_init(|| { - generalized_bulletproofs::tests::generators::(HELIOS_GENERATORS_LENGTH) - }) -} - -fn selene_generators() -> &'static Generators { - SELENE_GENERATORS.get_or_init(|| { - generalized_bulletproofs::tests::generators::(SELENE_GENERATORS_LENGTH) - }) -} - #[no_mangle] pub extern "C" fn helios_hash_init_point() -> HeliosPoint { - *HELIOS_HASH_INIT.get_or_init(|| HeliosPoint::random(&mut OsRng)) + HELIOS_HASH_INIT() } #[no_mangle] pub extern "C" fn selene_hash_init_point() -> SelenePoint { - *SELENE_HASH_INIT.get_or_init(|| SelenePoint::random(&mut OsRng)) + SELENE_HASH_INIT() } fn c_u8_32(bytes: [u8; 32]) -> *const u8 { @@ -94,30 +67,27 @@ pub extern "C" fn selene_point_from_bytes(selene_point: *const u8) -> SelenePoin ::read_G(&mut selene_point).unwrap() } -// Get the x coordinate of the ed25519 point #[allow(clippy::not_unsafe_ptr_arg_deref)] #[no_mangle] -pub extern "C" fn ed25519_point_to_selene_scalar(ed25519_point: *const u8) -> SeleneScalar { - let mut ed25519_point = unsafe { core::slice::from_raw_parts(ed25519_point, 32) }; +pub extern "C" fn selene_scalar_from_bytes(selene_scalar: *const u8) -> SeleneScalar { + let mut selene_scalar = unsafe { core::slice::from_raw_parts(selene_scalar, 32) }; // TODO: Return an error here (instead of unwrapping) - let ed25519_point = ::read_G(&mut ed25519_point).unwrap(); - - let xy_coords = ::G::to_xy(ed25519_point); - let x: SeleneScalar = xy_coords.0; - x + ::read_F(&mut selene_scalar).unwrap() } #[no_mangle] pub extern "C" fn selene_point_to_helios_scalar(selene_point: SelenePoint) -> HeliosScalar { let xy_coords = SelenePoint::to_xy(selene_point); - let x: HeliosScalar = xy_coords.0; + // TODO: Return an error here (instead of unwrapping) + let x: HeliosScalar = xy_coords.unwrap().0; x } #[no_mangle] pub extern "C" fn helios_point_to_selene_scalar(helios_point: HeliosPoint) -> SeleneScalar { let xy_coords = HeliosPoint::to_xy(helios_point); - let x: SeleneScalar = xy_coords.0; + // TODO: Return an error here (instead of unwrapping) + let x: SeleneScalar = xy_coords.unwrap().0; x } @@ -172,7 +142,7 @@ pub extern "C" fn hash_grow_helios( new_children: HeliosScalarSlice, ) -> CResult { let hash = hash_grow( - helios_generators(), + HELIOS_GENERATORS(), existing_hash, offset, existing_child_at_offset, @@ -194,7 +164,7 @@ pub extern "C" fn hash_trim_helios( child_to_grow_back: HeliosScalar, ) -> CResult { let hash = hash_trim( - helios_generators(), + HELIOS_GENERATORS(), existing_hash, offset, children.into(), @@ -216,7 +186,7 @@ pub extern "C" fn hash_grow_selene( new_children: SeleneScalarSlice, ) -> CResult { let hash = hash_grow( - selene_generators(), + SELENE_GENERATORS(), existing_hash, offset, existing_child_at_offset, @@ -238,7 +208,7 @@ pub extern "C" fn hash_trim_selene( child_to_grow_back: SeleneScalar, ) -> CResult { let hash = hash_trim( - selene_generators(), + SELENE_GENERATORS(), existing_hash, offset, children.into(), diff --git a/src/fcmp/tower_cycle.cpp b/src/fcmp/tower_cycle.cpp index 75c73af1c..691afc3f8 100644 --- a/src/fcmp/tower_cycle.cpp +++ b/src/fcmp/tower_cycle.cpp @@ -220,15 +220,9 @@ std::string Selene::to_string(const typename Selene::Point &point) const //---------------------------------------------------------------------------------------------------------------------- // Exposed helper functions //---------------------------------------------------------------------------------------------------------------------- -SeleneScalar ed_25519_point_to_scalar(const crypto::ec_point &point) +SeleneScalar selene_scalar_from_bytes(const rct::key &scalar) { - static_assert(sizeof(SeleneScalar) == sizeof(point), "size of selene scalar != size of ed25519 point"); - - // If this function receives the ec_point, this is fine - // If this function can receive a decompressed point, it'd be notably faster - // to extract the Wei25519 x coordinate from the C side of things and then - // pass that - return fcmp_rust::ed25519_point_to_selene_scalar((uint8_t*) &point.data); + return fcmp_rust::selene_scalar_from_bytes(scalar.bytes); } //---------------------------------------------------------------------------------------------------------------------- template diff --git a/src/fcmp/tower_cycle.h b/src/fcmp/tower_cycle.h index 6b0836384..a0454e5a9 100644 --- a/src/fcmp/tower_cycle.h +++ b/src/fcmp/tower_cycle.h @@ -30,6 +30,7 @@ #include "crypto/crypto.h" #include "fcmp_rust/fcmp++.h" +#include "ringct/rctTypes.h" #include @@ -190,8 +191,7 @@ public: }; //---------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------- -// Ed25519 point x-coordinates are Selene scalars -SeleneScalar ed_25519_point_to_scalar(const crypto::ec_point &point); +SeleneScalar selene_scalar_from_bytes(const rct::key &scalar); //---------------------------------------------------------------------------------------------------------------------- template void extend_zeroes(const C &curve, diff --git a/src/ringct/rctOps.cpp b/src/ringct/rctOps.cpp index 0e18cb461..4d9cefb75 100644 --- a/src/ringct/rctOps.cpp +++ b/src/ringct/rctOps.cpp @@ -725,4 +725,29 @@ namespace rct { sc_sub(masked.amount.bytes, masked.amount.bytes, sharedSec2.bytes); } } + + bool clear_torsion(const key &k, key &k_out) { + ge_p3 point; + if (ge_frombytes_vartime(&point, k.bytes) != 0) + return false; + // mul by inv 8, then mul by 8 + ge_p2 point_inv_8; + ge_scalarmult(&point_inv_8, INV_EIGHT.bytes, &point); + ge_p1p1 point_inv_8_mul_8; + ge_mul8(&point_inv_8_mul_8, &point_inv_8); + ge_p3 torsion_cleared_point; + ge_p1p1_to_p3(&torsion_cleared_point, &point_inv_8_mul_8); + ge_p3_tobytes(k_out.bytes, &torsion_cleared_point); + if (k_out == I) + return false; + return true; + } + + bool point_to_wei_x(const key &pub, key &wei_x) { + fe y; + if (fe_y_frombytes_vartime(y, pub.bytes) != 0) + return false; + fe_y_to_wei_x(wei_x.bytes, y); + return true; + } } diff --git a/src/ringct/rctOps.h b/src/ringct/rctOps.h index 0edd0308c..84db3e089 100644 --- a/src/ringct/rctOps.h +++ b/src/ringct/rctOps.h @@ -188,5 +188,8 @@ namespace rct { key genCommitmentMask(const key &sk); void ecdhEncode(ecdhTuple & unmasked, const key & sharedSec, bool v2); void ecdhDecode(ecdhTuple & masked, const key & sharedSec, bool v2); + + bool clear_torsion(const key &k, key &k_out); + bool point_to_wei_x(const key &pub, key &wei_x); } #endif /* RCTOPS_H */ diff --git a/src/ringct/rctTypes.h b/src/ringct/rctTypes.h index 1d237c6e2..c7138ed9b 100644 --- a/src/ringct/rctTypes.h +++ b/src/ringct/rctTypes.h @@ -762,6 +762,7 @@ namespace rct { static inline const rct::key &sk2rct(const crypto::secret_key &sk) { return (const rct::key&)sk; } static inline const rct::key &ki2rct(const crypto::key_image &ki) { return (const rct::key&)ki; } static inline const rct::key &hash2rct(const crypto::hash &h) { return (const rct::key&)h; } + static inline const rct::key &pt2rct(const crypto::ec_point &pt) { return (const rct::key&)pt; } static inline const crypto::public_key &rct2pk(const rct::key &k) { return (const crypto::public_key&)k; } static inline const crypto::secret_key &rct2sk(const rct::key &k) { return (const crypto::secret_key&)k; } static inline const crypto::key_image &rct2ki(const rct::key &k) { return (const crypto::key_image&)k; } diff --git a/tests/unit_tests/curve_trees.cpp b/tests/unit_tests/curve_trees.cpp index b476a33da..a71d0d239 100644 --- a/tests/unit_tests/curve_trees.cpp +++ b/tests/unit_tests/curve_trees.cpp @@ -31,6 +31,7 @@ #include "cryptonote_basic/cryptonote_format_utils.h" #include "curve_trees.h" #include "misc_log_ex.h" +#include "ringct/rctOps.h" #include "unit_tests_utils.h" #include @@ -759,7 +760,7 @@ static const std::vector generate_random_le crypto::generate_keys(O, o, o, false); crypto::generate_keys(C, c, c, false); - auto tuple_context = curve_trees.output_to_leaf_context(output_id, O, C); + auto tuple_context = curve_trees.output_to_leaf_context(output_id, O, rct::pk2rct(C)); tuples.emplace_back(std::move(tuple_context)); } @@ -773,7 +774,10 @@ static const Selene::Scalar generate_random_selene_scalar() crypto::public_key S; crypto::generate_keys(S, s, s, false); - return fcmp::tower_cycle::ed_25519_point_to_scalar(S); + + rct::key S_x; + CHECK_AND_ASSERT_THROW_MES(rct::point_to_wei_x(rct::pk2rct(S), S_x), "failed to convert to wei x"); + return fcmp::tower_cycle::selene_scalar_from_bytes(S_x); } //---------------------------------------------------------------------------------------------------------------------- static bool grow_tree(CurveTreesV1 &curve_trees,