Optimize conversion from output to leaf tuple

This commit is contained in:
j-berman 2024-08-02 22:32:03 -07:00
parent b90cee8bab
commit cbf6a5d618
16 changed files with 249 additions and 126 deletions

View File

@ -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(...)
{

View File

@ -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},

View File

@ -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);
}

View File

@ -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);

View File

@ -630,26 +630,14 @@ template<>
LeafTupleContext CurveTrees<Helios, Selene>::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<Helios, Selene>::LeafTuple CurveTrees<Helios, Selene>::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<Helios, Selene>::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 (...)
{

View File

@ -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;

View File

@ -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"

View File

@ -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" }

View File

@ -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);

View File

@ -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<Generators<RecommendedTranscript, Helios>> = OnceLock::new();
static SELENE_GENERATORS: OnceLock<Generators<RecommendedTranscript, Selene>> = OnceLock::new();
static HELIOS_HASH_INIT: OnceLock<HeliosPoint> = OnceLock::new();
static SELENE_HASH_INIT: OnceLock<SelenePoint> = OnceLock::new();
// TODO: Don't use random generators
fn helios_generators() -> &'static Generators<RecommendedTranscript, Helios> {
HELIOS_GENERATORS.get_or_init(|| {
generalized_bulletproofs::tests::generators::<Helios>(HELIOS_GENERATORS_LENGTH)
})
}
fn selene_generators() -> &'static Generators<RecommendedTranscript, Selene> {
SELENE_GENERATORS.get_or_init(|| {
generalized_bulletproofs::tests::generators::<Selene>(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
<Selene>::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 = <Ed25519>::read_G(&mut ed25519_point).unwrap();
let xy_coords = <Ed25519 as Ciphersuite>::G::to_xy(ed25519_point);
let x: SeleneScalar = xy_coords.0;
x
<Selene>::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<HeliosPoint, ()> {
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<HeliosPoint, ()> {
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<SelenePoint, ()> {
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<SelenePoint, ()> {
let hash = hash_trim(
selene_generators(),
SELENE_GENERATORS(),
existing_hash,
offset,
children.into(),

View File

@ -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<typename C>

View File

@ -30,6 +30,7 @@
#include "crypto/crypto.h"
#include "fcmp_rust/fcmp++.h"
#include "ringct/rctTypes.h"
#include <string>
@ -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<typename C>
void extend_zeroes(const C &curve,

View File

@ -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;
}
}

View File

@ -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 */

View File

@ -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; }

View File

@ -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 <algorithm>
@ -759,7 +760,7 @@ static const std::vector<fcmp::curve_trees::LeafTupleContext> 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,