use crate::{MPI, RandomNumberGenerator, utils::*};
use botan_sys::*;
use core::ops::Add;
#[cfg(botan_ffi_20260506)]
use crate::EcGroup;
#[cfg(botan_ffi_20260506)]
#[derive(Debug)]
pub struct EcScalar {
obj: botan_ec_scalar_t,
}
#[cfg(botan_ffi_20260506)]
unsafe impl Sync for EcScalar {}
#[cfg(botan_ffi_20260506)]
unsafe impl Send for EcScalar {}
#[cfg(botan_ffi_20260506)]
botan_impl_drop!(EcScalar, botan_ec_scalar_destroy);
#[cfg(botan_ffi_20260506)]
impl EcScalar {
pub(crate) fn handle(&self) -> botan_ec_scalar_t {
self.obj
}
pub(crate) fn from_handle(obj: botan_ec_scalar_t) -> Self {
Self { obj }
}
pub fn random(group: &EcGroup, rng: &mut RandomNumberGenerator) -> Result<Self> {
let obj = botan_init!(botan_ec_scalar_random, group.handle(), rng.handle())?;
Ok(Self { obj })
}
pub fn from_mpi(group: &EcGroup, mpi: &MPI) -> Result<Self> {
let obj = botan_init!(botan_ec_scalar_from_mp, group.handle(), mpi.handle())?;
Ok(Self { obj })
}
pub fn to_mpi(&self) -> Result<MPI> {
let obj = botan_init_at!(botan_ec_scalar_to_mp, self.obj;)?;
MPI::from_handle(obj)
}
}
#[cfg(botan_ffi_20260506)]
#[derive(Debug)]
pub struct EcPoint {
obj: botan_ec_point_t,
}
#[cfg(botan_ffi_20260506)]
unsafe impl Sync for EcPoint {}
#[cfg(botan_ffi_20260506)]
unsafe impl Send for EcPoint {}
#[cfg(botan_ffi_20260506)]
botan_impl_drop!(EcPoint, botan_ec_point_destroy);
#[cfg(botan_ffi_20260506)]
impl EcPoint {
pub(crate) fn handle(&self) -> botan_ec_point_t {
self.obj
}
pub fn identity(group: &EcGroup) -> Result<Self> {
let obj = botan_init!(botan_ec_point_identity, group.handle())?;
Ok(Self { obj })
}
pub fn generator(group: &EcGroup) -> Result<Self> {
let obj = botan_init!(botan_ec_point_generator, group.handle())?;
Ok(Self { obj })
}
pub fn from_xy(group: &EcGroup, x: &MPI, y: &MPI) -> Result<Self> {
let obj = botan_init!(
botan_ec_point_from_xy,
group.handle(),
x.handle(),
y.handle()
)?;
Ok(Self { obj })
}
pub fn from_bytes(group: &EcGroup, bytes: &[u8]) -> Result<Self> {
let obj = botan_init!(
botan_ec_point_from_bytes,
group.handle(),
bytes.as_ptr(),
bytes.len()
)?;
Ok(Self { obj })
}
pub fn is_identity(&self) -> Result<bool> {
botan_bool_in_rc!(botan_ec_point_is_identity, self.obj)
}
pub fn is_equal(&self, other: &EcPoint) -> Result<bool> {
botan_bool_in_rc!(botan_ec_point_equal, self.obj, other.obj)
}
pub fn negate(&self) -> Result<EcPoint> {
let obj = botan_init!(botan_ec_point_negate, self.obj)?;
Ok(Self { obj })
}
pub fn pt_add(&self, other: &EcPoint) -> Result<EcPoint> {
let obj = botan_init!(botan_ec_point_add, self.obj, other.handle())?;
Ok(Self { obj })
}
pub fn mul(&self, scalar: &EcScalar, rng: &mut RandomNumberGenerator) -> Result<Self> {
let obj = botan_init!(botan_ec_point_mul, self.obj, scalar.handle(), rng.handle())?;
Ok(Self { obj })
}
pub fn to_x_bytes(&self) -> Result<Vec<u8>> {
call_botan_ffi_viewing_vec_u8(&|ctx, cb| unsafe {
botan_ec_point_view_x_bytes(self.obj, ctx, cb)
})
}
pub fn to_y_bytes(&self) -> Result<Vec<u8>> {
call_botan_ffi_viewing_vec_u8(&|ctx, cb| unsafe {
botan_ec_point_view_y_bytes(self.obj, ctx, cb)
})
}
pub fn to_xy_bytes(&self) -> Result<Vec<u8>> {
call_botan_ffi_viewing_vec_u8(&|ctx, cb| unsafe {
botan_ec_point_view_xy_bytes(self.obj, ctx, cb)
})
}
pub fn to_uncompressed(&self) -> Result<Vec<u8>> {
call_botan_ffi_viewing_vec_u8(&|ctx, cb| unsafe {
botan_ec_point_view_uncompressed(self.obj, ctx, cb)
})
}
pub fn to_compressed(&self) -> Result<Vec<u8>> {
call_botan_ffi_viewing_vec_u8(&|ctx, cb| unsafe {
botan_ec_point_view_compressed(self.obj, ctx, cb)
})
}
}
#[cfg(botan_ffi_20260506)]
impl PartialEq for EcPoint {
fn eq(&self, other: &Self) -> bool {
self.is_equal(other)
.expect("botan_ec_point_equal should succeed")
}
}
#[cfg(botan_ffi_20260506)]
impl Eq for EcPoint {}
#[cfg(botan_ffi_20260506)]
impl<'b> Add<&'b EcPoint> for &EcPoint {
type Output = EcPoint;
fn add(self, other: &'b EcPoint) -> Self::Output {
self.pt_add(other)
.expect("botan_ec_point_add should succeed")
}
}
#[cfg(botan_ffi_20260506)]
impl Add<&EcPoint> for EcPoint {
type Output = EcPoint;
fn add(self, other: &EcPoint) -> EcPoint {
(&self).add(other)
}
}
#[cfg(botan_ffi_20260506)]
impl Add<EcPoint> for &EcPoint {
type Output = EcPoint;
fn add(self, other: EcPoint) -> EcPoint {
self.add(&other)
}
}
#[cfg(botan_ffi_20260506)]
impl Add<EcPoint> for EcPoint {
type Output = EcPoint;
fn add(self, other: EcPoint) -> EcPoint {
(&self).add(&other)
}
}