use crate::{G, Point, Scalar, g, marker::*};
#[derive(Clone, Copy, Debug)]
pub struct KeyPair<T = Normal, Z = NonZero> {
sk: Scalar<Secret, Z>,
pk: Point<T, Public, Z>,
}
impl<T1: PointType, T2: PointType> PartialEq<KeyPair<T2>> for KeyPair<T1> {
fn eq(&self, other: &KeyPair<T2>) -> bool {
self.pk == other.pk
}
}
impl<T: PointType> Eq for KeyPair<T> {}
impl<Z: ZeroChoice> KeyPair<Normal, Z> {
pub fn new(secret_key: Scalar<Secret, Z>) -> Self {
Self {
pk: g!(secret_key * G).normalize(),
sk: secret_key,
}
}
}
impl KeyPair<EvenY> {
pub fn new_xonly(mut secret_key: Scalar) -> Self {
let pk = Point::even_y_from_scalar_mul(G, &mut secret_key);
Self { sk: secret_key, pk }
}
}
impl<T, Z> KeyPair<T, Z> {
pub fn secret_key(&self) -> &Scalar<Secret, Z> {
&self.sk
}
pub fn public_key(&self) -> Point<T, Public, Z>
where
T: Copy,
{
self.pk
}
pub fn as_tuple(&self) -> (Scalar<Secret, Z>, Point<T, Public, Z>)
where
T: Copy,
{
(self.sk, self.pk)
}
}
impl KeyPair<Normal, Zero> {
pub fn zero() -> Self {
KeyPair {
sk: Scalar::zero(),
pk: Point::zero(),
}
}
}
impl From<KeyPair<EvenY>> for KeyPair<Normal> {
fn from(xonly: KeyPair<EvenY>) -> Self {
Self {
sk: xonly.sk,
pk: xonly.pk.normalize(),
}
}
}
impl From<KeyPair<Normal>> for KeyPair<EvenY> {
fn from(kp: KeyPair<Normal>) -> Self {
let mut sk = kp.sk;
let (pk, needs_negation) = kp.pk.into_point_with_even_y();
sk.conditional_negate(needs_negation);
Self { sk, pk }
}
}
crate::impl_serialize! {
fn to_bytes<T, Z>(kp: &KeyPair<T, Z>) -> [u8;32] {
kp.secret_key().to_bytes()
}
}
crate::impl_fromstr_deserialize! {
name => "secp256k1 scalar",
fn from_bytes(bytes: [u8;32]) -> Option<KeyPair<Normal>> {
let sk = Scalar::from_bytes(bytes)?.non_zero()?;
Some(KeyPair::<Normal>::new(sk))
}
}
crate::impl_fromstr_deserialize! {
name => "secp256k1 scalar",
fn from_bytes(bytes: [u8;32]) -> Option<KeyPair<EvenY>> {
let sk = Scalar::from_bytes(bytes)?.non_zero()?;
Some(KeyPair::new_xonly(sk))
}
}