Curve25519 syscall group ops (#25071)
* zk-token-sdk: implement group ops trait for curve25519 * zk-token-sdk: extend syscall trait implementation for group ops for ristretto * zk-token-sdk: register curve25519 group ops to bpf loader * zk-token-sdk: update curve25519_syscall_enabled address
This commit is contained in:
parent
e6c02f30dd
commit
aba6a89517
|
@ -57,10 +57,22 @@ pub struct ComputeBudget {
|
||||||
pub syscall_base_cost: u64,
|
pub syscall_base_cost: u64,
|
||||||
/// Number of compute units consumed to call zktoken_crypto_op
|
/// Number of compute units consumed to call zktoken_crypto_op
|
||||||
pub zk_token_elgamal_op_cost: u64, // to be replaced by curve25519 operations
|
pub zk_token_elgamal_op_cost: u64, // to be replaced by curve25519 operations
|
||||||
/// Number of compute units consumed to add/sub two edwards points
|
/// Number of compute units consumed to validate a curve25519 edwards point
|
||||||
pub curve25519_edwards_validate_point_cost: u64,
|
pub curve25519_edwards_validate_point_cost: u64,
|
||||||
/// Number of compute units consumed to add/sub two ristretto points
|
/// Number of compute units consumed to add two curve25519 edwards points
|
||||||
|
pub curve25519_edwards_add_cost: u64,
|
||||||
|
/// Number of compute units consumed to subtract two curve25519 edwards points
|
||||||
|
pub curve25519_edwards_subtract_cost: u64,
|
||||||
|
/// Number of compute units consumed to multiply a curve25519 edwards point
|
||||||
|
pub curve25519_edwards_multiply_cost: u64,
|
||||||
|
/// Number of compute units consumed to validate a curve25519 ristretto point
|
||||||
pub curve25519_ristretto_validate_point_cost: u64,
|
pub curve25519_ristretto_validate_point_cost: u64,
|
||||||
|
/// Number of compute units consumed to add two curve25519 ristretto points
|
||||||
|
pub curve25519_ristretto_add_cost: u64,
|
||||||
|
/// Number of compute units consumed to subtract two curve25519 ristretto points
|
||||||
|
pub curve25519_ristretto_subtract_cost: u64,
|
||||||
|
/// Number of compute units consumed to multiply a curve25519 ristretto point
|
||||||
|
pub curve25519_ristretto_multiply_cost: u64,
|
||||||
/// Optional program heap region size, if `None` then loader default
|
/// Optional program heap region size, if `None` then loader default
|
||||||
pub heap_size: Option<usize>,
|
pub heap_size: Option<usize>,
|
||||||
/// Number of compute units per additional 32k heap above the default (~.5
|
/// Number of compute units per additional 32k heap above the default (~.5
|
||||||
|
@ -96,8 +108,14 @@ impl ComputeBudget {
|
||||||
secp256k1_recover_cost: 25_000,
|
secp256k1_recover_cost: 25_000,
|
||||||
syscall_base_cost: 100,
|
syscall_base_cost: 100,
|
||||||
zk_token_elgamal_op_cost: 25_000,
|
zk_token_elgamal_op_cost: 25_000,
|
||||||
curve25519_edwards_validate_point_cost: 25_000, // TODO: precisely determine cost
|
curve25519_edwards_validate_point_cost: 25_000, // TODO: precisely determine curve25519 costs
|
||||||
|
curve25519_edwards_add_cost: 25_000,
|
||||||
|
curve25519_edwards_subtract_cost: 25_000,
|
||||||
|
curve25519_edwards_multiply_cost: 25_000,
|
||||||
curve25519_ristretto_validate_point_cost: 25_000,
|
curve25519_ristretto_validate_point_cost: 25_000,
|
||||||
|
curve25519_ristretto_add_cost: 25_000,
|
||||||
|
curve25519_ristretto_subtract_cost: 25_000,
|
||||||
|
curve25519_ristretto_multiply_cost: 25_000,
|
||||||
heap_size: None,
|
heap_size: None,
|
||||||
heap_cost: 8,
|
heap_cost: 8,
|
||||||
mem_op_base_cost: 10,
|
mem_op_base_cost: 10,
|
||||||
|
|
|
@ -261,6 +261,13 @@ pub fn register_syscalls(
|
||||||
SyscallCurvePointValidation::init,
|
SyscallCurvePointValidation::init,
|
||||||
SyscallCurvePointValidation::call,
|
SyscallCurvePointValidation::call,
|
||||||
)?;
|
)?;
|
||||||
|
register_feature_gated_syscall!(
|
||||||
|
syscall_registry,
|
||||||
|
curve25519_syscall_enabled,
|
||||||
|
b"sol_curve25519_point_validation",
|
||||||
|
SyscallCurveGroupOps::init,
|
||||||
|
SyscallCurveGroupOps::call,
|
||||||
|
)?;
|
||||||
|
|
||||||
// Sysvars
|
// Sysvars
|
||||||
syscall_registry.register_syscall_by_name(
|
syscall_registry.register_syscall_by_name(
|
||||||
|
@ -1979,6 +1986,264 @@ declare_syscall!(
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
declare_syscall!(
|
||||||
|
// Elliptic Curve Group Operations
|
||||||
|
//
|
||||||
|
// Currently, only curve25519 Edwards and Ristretto representations are supported
|
||||||
|
SyscallCurveGroupOps,
|
||||||
|
fn call(
|
||||||
|
&mut self,
|
||||||
|
curve_id: u64,
|
||||||
|
group_op: u64,
|
||||||
|
left_input_addr: u64,
|
||||||
|
right_input_addr: u64,
|
||||||
|
result_point_addr: u64,
|
||||||
|
memory_mapping: &MemoryMapping,
|
||||||
|
result: &mut Result<u64, EbpfError<BpfError>>,
|
||||||
|
) {
|
||||||
|
use solana_zk_token_sdk::curve25519::{
|
||||||
|
curve_syscall_traits::*, edwards, ristretto, scalar,
|
||||||
|
};
|
||||||
|
|
||||||
|
let invoke_context = question_mark!(
|
||||||
|
self.invoke_context
|
||||||
|
.try_borrow()
|
||||||
|
.map_err(|_| SyscallError::InvokeContextBorrowFailed),
|
||||||
|
result
|
||||||
|
);
|
||||||
|
|
||||||
|
match curve_id {
|
||||||
|
CURVE25519_EDWARDS => match group_op {
|
||||||
|
ADD => {
|
||||||
|
let cost = invoke_context
|
||||||
|
.get_compute_budget()
|
||||||
|
.curve25519_edwards_add_cost;
|
||||||
|
question_mark!(invoke_context.get_compute_meter().consume(cost), result);
|
||||||
|
|
||||||
|
let left_point = question_mark!(
|
||||||
|
translate_type::<edwards::PodEdwardsPoint>(
|
||||||
|
memory_mapping,
|
||||||
|
left_input_addr,
|
||||||
|
invoke_context.get_check_aligned(),
|
||||||
|
),
|
||||||
|
result
|
||||||
|
);
|
||||||
|
let right_point = question_mark!(
|
||||||
|
translate_type::<edwards::PodEdwardsPoint>(
|
||||||
|
memory_mapping,
|
||||||
|
right_input_addr,
|
||||||
|
invoke_context.get_check_aligned(),
|
||||||
|
),
|
||||||
|
result
|
||||||
|
);
|
||||||
|
|
||||||
|
if let Some(result_point) = edwards::add_edwards(left_point, right_point) {
|
||||||
|
*question_mark!(
|
||||||
|
translate_type_mut::<edwards::PodEdwardsPoint>(
|
||||||
|
memory_mapping,
|
||||||
|
result_point_addr,
|
||||||
|
invoke_context.get_check_aligned(),
|
||||||
|
),
|
||||||
|
result
|
||||||
|
) = result_point;
|
||||||
|
*result = Ok(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SUB => {
|
||||||
|
let cost = invoke_context
|
||||||
|
.get_compute_budget()
|
||||||
|
.curve25519_edwards_subtract_cost;
|
||||||
|
question_mark!(invoke_context.get_compute_meter().consume(cost), result);
|
||||||
|
|
||||||
|
let left_point = question_mark!(
|
||||||
|
translate_type::<edwards::PodEdwardsPoint>(
|
||||||
|
memory_mapping,
|
||||||
|
left_input_addr,
|
||||||
|
invoke_context.get_check_aligned(),
|
||||||
|
),
|
||||||
|
result
|
||||||
|
);
|
||||||
|
let right_point = question_mark!(
|
||||||
|
translate_type::<edwards::PodEdwardsPoint>(
|
||||||
|
memory_mapping,
|
||||||
|
right_input_addr,
|
||||||
|
invoke_context.get_check_aligned(),
|
||||||
|
),
|
||||||
|
result
|
||||||
|
);
|
||||||
|
|
||||||
|
if let Some(result_point) = edwards::subtract_edwards(left_point, right_point) {
|
||||||
|
*question_mark!(
|
||||||
|
translate_type_mut::<edwards::PodEdwardsPoint>(
|
||||||
|
memory_mapping,
|
||||||
|
result_point_addr,
|
||||||
|
invoke_context.get_check_aligned(),
|
||||||
|
),
|
||||||
|
result
|
||||||
|
) = result_point;
|
||||||
|
*result = Ok(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MUL => {
|
||||||
|
let cost = invoke_context
|
||||||
|
.get_compute_budget()
|
||||||
|
.curve25519_edwards_multiply_cost;
|
||||||
|
question_mark!(invoke_context.get_compute_meter().consume(cost), result);
|
||||||
|
|
||||||
|
let scalar = question_mark!(
|
||||||
|
translate_type::<scalar::PodScalar>(
|
||||||
|
memory_mapping,
|
||||||
|
left_input_addr,
|
||||||
|
invoke_context.get_check_aligned(),
|
||||||
|
),
|
||||||
|
result
|
||||||
|
);
|
||||||
|
let input_point = question_mark!(
|
||||||
|
translate_type::<edwards::PodEdwardsPoint>(
|
||||||
|
memory_mapping,
|
||||||
|
right_input_addr,
|
||||||
|
invoke_context.get_check_aligned(),
|
||||||
|
),
|
||||||
|
result
|
||||||
|
);
|
||||||
|
|
||||||
|
if let Some(result_point) = edwards::multiply_edwards(scalar, input_point) {
|
||||||
|
*question_mark!(
|
||||||
|
translate_type_mut::<edwards::PodEdwardsPoint>(
|
||||||
|
memory_mapping,
|
||||||
|
result_point_addr,
|
||||||
|
invoke_context.get_check_aligned(),
|
||||||
|
),
|
||||||
|
result
|
||||||
|
) = result_point;
|
||||||
|
*result = Ok(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
*result = Ok(1);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
CURVE25519_RISTRETTO => match group_op {
|
||||||
|
ADD => {
|
||||||
|
let cost = invoke_context
|
||||||
|
.get_compute_budget()
|
||||||
|
.curve25519_ristretto_add_cost;
|
||||||
|
question_mark!(invoke_context.get_compute_meter().consume(cost), result);
|
||||||
|
|
||||||
|
let left_point = question_mark!(
|
||||||
|
translate_type::<ristretto::PodRistrettoPoint>(
|
||||||
|
memory_mapping,
|
||||||
|
left_input_addr,
|
||||||
|
invoke_context.get_check_aligned(),
|
||||||
|
),
|
||||||
|
result
|
||||||
|
);
|
||||||
|
let right_point = question_mark!(
|
||||||
|
translate_type::<ristretto::PodRistrettoPoint>(
|
||||||
|
memory_mapping,
|
||||||
|
right_input_addr,
|
||||||
|
invoke_context.get_check_aligned(),
|
||||||
|
),
|
||||||
|
result
|
||||||
|
);
|
||||||
|
|
||||||
|
if let Some(result_point) = ristretto::add_ristretto(left_point, right_point) {
|
||||||
|
*question_mark!(
|
||||||
|
translate_type_mut::<ristretto::PodRistrettoPoint>(
|
||||||
|
memory_mapping,
|
||||||
|
result_point_addr,
|
||||||
|
invoke_context.get_check_aligned(),
|
||||||
|
),
|
||||||
|
result
|
||||||
|
) = result_point;
|
||||||
|
*result = Ok(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SUB => {
|
||||||
|
let cost = invoke_context
|
||||||
|
.get_compute_budget()
|
||||||
|
.curve25519_ristretto_subtract_cost;
|
||||||
|
question_mark!(invoke_context.get_compute_meter().consume(cost), result);
|
||||||
|
|
||||||
|
let left_point = question_mark!(
|
||||||
|
translate_type::<ristretto::PodRistrettoPoint>(
|
||||||
|
memory_mapping,
|
||||||
|
left_input_addr,
|
||||||
|
invoke_context.get_check_aligned(),
|
||||||
|
),
|
||||||
|
result
|
||||||
|
);
|
||||||
|
let right_point = question_mark!(
|
||||||
|
translate_type::<ristretto::PodRistrettoPoint>(
|
||||||
|
memory_mapping,
|
||||||
|
right_input_addr,
|
||||||
|
invoke_context.get_check_aligned(),
|
||||||
|
),
|
||||||
|
result
|
||||||
|
);
|
||||||
|
|
||||||
|
if let Some(result_point) =
|
||||||
|
ristretto::subtract_ristretto(left_point, right_point)
|
||||||
|
{
|
||||||
|
*question_mark!(
|
||||||
|
translate_type_mut::<ristretto::PodRistrettoPoint>(
|
||||||
|
memory_mapping,
|
||||||
|
result_point_addr,
|
||||||
|
invoke_context.get_check_aligned(),
|
||||||
|
),
|
||||||
|
result
|
||||||
|
) = result_point;
|
||||||
|
*result = Ok(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MUL => {
|
||||||
|
let cost = invoke_context
|
||||||
|
.get_compute_budget()
|
||||||
|
.curve25519_ristretto_multiply_cost;
|
||||||
|
question_mark!(invoke_context.get_compute_meter().consume(cost), result);
|
||||||
|
|
||||||
|
let scalar = question_mark!(
|
||||||
|
translate_type::<scalar::PodScalar>(
|
||||||
|
memory_mapping,
|
||||||
|
left_input_addr,
|
||||||
|
invoke_context.get_check_aligned(),
|
||||||
|
),
|
||||||
|
result
|
||||||
|
);
|
||||||
|
let input_point = question_mark!(
|
||||||
|
translate_type::<ristretto::PodRistrettoPoint>(
|
||||||
|
memory_mapping,
|
||||||
|
right_input_addr,
|
||||||
|
invoke_context.get_check_aligned(),
|
||||||
|
),
|
||||||
|
result
|
||||||
|
);
|
||||||
|
|
||||||
|
if let Some(result_point) = ristretto::multiply_ristretto(scalar, input_point) {
|
||||||
|
*question_mark!(
|
||||||
|
translate_type_mut::<ristretto::PodRistrettoPoint>(
|
||||||
|
memory_mapping,
|
||||||
|
result_point_addr,
|
||||||
|
invoke_context.get_check_aligned(),
|
||||||
|
),
|
||||||
|
result
|
||||||
|
) = result_point;
|
||||||
|
*result = Ok(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
*result = Ok(1);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_ => {
|
||||||
|
*result = Ok(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
declare_syscall!(
|
declare_syscall!(
|
||||||
// Blake3
|
// Blake3
|
||||||
SyscallBlake3,
|
SyscallBlake3,
|
||||||
|
|
|
@ -149,9 +149,8 @@ pub mod zk_token_sdk_enabled {
|
||||||
solana_sdk::declare_id!("zk1snxsc6Fh3wsGNbbHAJNHiJoYgF29mMnTSusGx5EJ");
|
solana_sdk::declare_id!("zk1snxsc6Fh3wsGNbbHAJNHiJoYgF29mMnTSusGx5EJ");
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: temporary address for now
|
|
||||||
pub mod curve25519_syscall_enabled {
|
pub mod curve25519_syscall_enabled {
|
||||||
solana_sdk::declare_id!("curve25519111111111111111111111111111111111");
|
solana_sdk::declare_id!("7rcw5UtqgDTBBv2EcynNfYckgdAaH1MAsCjKgXMkN7Ri");
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod versioned_tx_message_enabled {
|
pub mod versioned_tx_message_enabled {
|
||||||
|
|
|
@ -86,9 +86,20 @@ pub const MUL: u64 = 2;
|
||||||
extern "C" {
|
extern "C" {
|
||||||
pub fn sol_curve_validate_point(curve_id: u64, point: *const u8, result: *mut u8) -> u64;
|
pub fn sol_curve_validate_point(curve_id: u64, point: *const u8, result: *mut u8) -> u64;
|
||||||
|
|
||||||
pub fn sol_curve_op(curve_id: u64, op_id: u64, point: *const u8, result: *mut u8) -> u64;
|
pub fn sol_curve_op(
|
||||||
|
curve_id: u64,
|
||||||
|
op_id: u64,
|
||||||
|
left_point: *const u8,
|
||||||
|
right_point: *const u8,
|
||||||
|
result: *mut u8,
|
||||||
|
) -> u64;
|
||||||
|
|
||||||
pub fn sol_curve_multiscalar_mul(curve_id: u64, point: *const u8, result: *mut u8) -> u64;
|
pub fn sol_curve_multiscalar_mul(
|
||||||
|
curve_id: u64,
|
||||||
|
scalars: *const u8,
|
||||||
|
points: *const u8,
|
||||||
|
result: *mut u8,
|
||||||
|
) -> u64;
|
||||||
|
|
||||||
pub fn sol_curve_pairing_map(curve_id: u64, point: *const u8, result: *mut u8) -> u64;
|
pub fn sol_curve_pairing_map(curve_id: u64, point: *const u8, result: *mut u8) -> u64;
|
||||||
}
|
}
|
||||||
|
|
|
@ -129,7 +129,9 @@ mod target_arch {
|
||||||
mod target_arch {
|
mod target_arch {
|
||||||
use {
|
use {
|
||||||
super::*,
|
super::*,
|
||||||
crate::curve25519::curve_syscall_traits::{sol_curve_validate_point, CURVE25519_EDWARDS},
|
crate::curve25519::curve_syscall_traits::{
|
||||||
|
sol_curve_op, sol_curve_validate_point, ADD, CURVE25519_EDWARDS, MUL, SUB,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn validate_edwards(point: &PodEdwardsPoint) -> bool {
|
pub fn validate_edwards(point: &PodEdwardsPoint) -> bool {
|
||||||
|
@ -141,9 +143,74 @@ mod target_arch {
|
||||||
&mut validate_result,
|
&mut validate_result,
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
result == 0
|
result == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn add_edwards(
|
||||||
|
left_point: &PodEdwardsPoint,
|
||||||
|
right_point: &PodEdwardsPoint,
|
||||||
|
) -> Option<PodEdwardsPoint> {
|
||||||
|
let mut result_point = PodEdwardsPoint::zeroed();
|
||||||
|
let result = unsafe {
|
||||||
|
sol_curve_op(
|
||||||
|
CURVE25519_EDWARDS,
|
||||||
|
ADD,
|
||||||
|
&left_point.0 as *const u8,
|
||||||
|
&right_point.0 as *const u8,
|
||||||
|
&mut result_point.0 as *mut u8,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
if result == 0 {
|
||||||
|
Some(result_point)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn subtract_edwards(
|
||||||
|
left_point: &PodEdwardsPoint,
|
||||||
|
right_point: &PodEdwardsPoint,
|
||||||
|
) -> Option<PodEdwardsPoint> {
|
||||||
|
let mut result_point = PodEdwardsPoint::zeroed();
|
||||||
|
let result = unsafe {
|
||||||
|
sol_curve_op(
|
||||||
|
CURVE25519_EDWARDS,
|
||||||
|
SUB,
|
||||||
|
&left_point.0 as *const u8,
|
||||||
|
&right_point.0 as *const u8,
|
||||||
|
&mut result_point.0 as *mut u8,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
if result == 0 {
|
||||||
|
Some(result_point)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn multiply_edwards(
|
||||||
|
left_point: &PodEdwardsPoint,
|
||||||
|
right_point: &PodEdwardsPoint,
|
||||||
|
) -> Option<PodEdwardsPoint> {
|
||||||
|
let mut result_point = PodEdwardsPoint::zeroed();
|
||||||
|
let result = unsafe {
|
||||||
|
sol_curve_op(
|
||||||
|
CURVE25519_EDWARDS,
|
||||||
|
MUL,
|
||||||
|
&left_point.0 as *const u8,
|
||||||
|
&right_point.0 as *const u8,
|
||||||
|
&mut result_point.0 as *mut u8,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
if result == 0 {
|
||||||
|
Some(result_point)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
|
@ -130,7 +130,9 @@ mod target_arch {
|
||||||
mod target_arch {
|
mod target_arch {
|
||||||
use {
|
use {
|
||||||
super::*,
|
super::*,
|
||||||
crate::curve25519::curve_syscall_traits::{sol_curve_validate_point, CURVE25519_RISTRETTO},
|
crate::curve25519::curve_syscall_traits::{
|
||||||
|
sol_curve_op, sol_curve_validate_point, ADD, CURVE25519_RISTRETTO, MUL, SUB,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn validate_ristretto(point: &PodRistrettoPoint) -> bool {
|
pub fn validate_ristretto(point: &PodRistrettoPoint) -> bool {
|
||||||
|
@ -145,6 +147,72 @@ mod target_arch {
|
||||||
|
|
||||||
result == 0
|
result == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn add_ristretto(
|
||||||
|
left_point: &PodRistrettoPoint,
|
||||||
|
right_point: &PodRistrettoPoint,
|
||||||
|
) -> Option<PodRistrettoPoint> {
|
||||||
|
let mut result_point = PodRistrettoPoint::zeroed();
|
||||||
|
let result = unsafe {
|
||||||
|
sol_curve_op(
|
||||||
|
CURVE25519_RISTRETTO,
|
||||||
|
ADD,
|
||||||
|
&left_point.0 as *const u8,
|
||||||
|
&right_point.0 as *const u8,
|
||||||
|
&mut result_point.0 as *mut u8,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
if result == 0 {
|
||||||
|
Some(result_point)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn subtract_ristretto(
|
||||||
|
left_point: &PodRistrettoPoint,
|
||||||
|
right_point: &PodRistrettoPoint,
|
||||||
|
) -> Option<PodRistrettoPoint> {
|
||||||
|
let mut result_point = PodRistrettoPoint::zeroed();
|
||||||
|
let result = unsafe {
|
||||||
|
sol_curve_op(
|
||||||
|
CURVE25519_RISTRETTO,
|
||||||
|
SUB,
|
||||||
|
&left_point.0 as *const u8,
|
||||||
|
&right_point.0 as *const u8,
|
||||||
|
&mut result_point.0 as *mut u8,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
if result == 0 {
|
||||||
|
Some(result_point)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn multiply_ristretto(
|
||||||
|
left_point: &PodRistrettoPoint,
|
||||||
|
right_point: &PodRistrettoPoint,
|
||||||
|
) -> Option<PodRistrettoPoint> {
|
||||||
|
let mut result_point = PodRistrettoPoint::zeroed();
|
||||||
|
let result = unsafe {
|
||||||
|
sol_curve_op(
|
||||||
|
CURVE25519_RISTRETTO,
|
||||||
|
MUL,
|
||||||
|
&left_point.0 as *const u8,
|
||||||
|
&right_point.0 as *const u8,
|
||||||
|
&mut result_point.0 as *mut u8,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
if result == 0 {
|
||||||
|
Some(result_point)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
Loading…
Reference in New Issue