Struct secp256kfun::Point
source · pub struct Point<T = Normal, S = Public, Z = NonZero>(/* private fields */);
Expand description
A point on the secp256k1 elliptic curve.
A Point<T,S,Z>
marked with Z = NonZero
is any two integers modulo p
(x,y)
that satisfy:
y^2 = 3*x + 7 mod p
where p = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F
.
For every valid x-coordinate, there will be exactly two valid y-coordinates which will be the negation modulo p of each other.
If the point is marked Z = Zero
then it may also be point at infinity which is the identity element of the group.
§Markers
A Point<T,S,Z>
has three types parameters.
T
: APointType
used to reason about what the point can do and to specialize point operations.S
: ASecrecy
to determine whether operations on this point should be done in constant-time or not. By default points arePublic
so operations run in variable time.Z
: AZeroChoice
to keep track of whether the point might be zero (the point at infinity) or is guaranteed to be non-zero.
§Serialization
Only points that are normalized (i.e. T
≠ NonNormal
) can be serialized. A Point that is
EvenY
points serialize to and from their 32-byte x-only representation.
Normal
points serialize to and from the standard 33-byte representation specified in
Standards for Efficient Cryptography (the same as Point::to_bytes
). Points that are
are zero (see is_zero
) will serialize to [0u8;33]
.
Implementations§
source§impl Point<Normal, Public, NonZero>
impl Point<Normal, Public, NonZero>
sourcepub fn random(rng: &mut impl RngCore) -> Self
pub fn random(rng: &mut impl RngCore) -> Self
Samples a point uniformly from the group.
§Examples
Generate a random point from thread_rng
.
let random_point = Point::random(&mut rand::thread_rng());
sourcepub fn from_bytes_uncompressed(bytes: [u8; 65]) -> Option<Self>
pub fn from_bytes_uncompressed(bytes: [u8; 65]) -> Option<Self>
Creates a Point from a 65-byte uncompressed encoding specified in
Standards for Efficient Cryptography. The first byte must be
0x04
. The remaining 64 bytes must encode a valid x and y coordinate
on the curve. If the conditions are not met then it will return None
.
source§impl<Z: ZeroChoice, S> Point<Normal, S, Z>
impl<Z: ZeroChoice, S> Point<Normal, S, Z>
sourcepub fn from_bytes(bytes: [u8; 33]) -> Option<Self>
pub fn from_bytes(bytes: [u8; 33]) -> Option<Self>
Creates a Point the compressed encoding specified in Standards for
Efficient Cryptography. This is the typical encoding used in
Bitcoin. The first byte must be 0x02
or 0x03
to indicate that the
y-coordinate is even or odd respectively. The remaining 32 bytes must
encode an x-coordinate on the curve. If these conditions are not then
it will return None
.
§Examples
use secp256kfun::{marker::*, Point, G};
let bytes = [
2, 121, 190, 102, 126, 249, 220, 187, 172, 85, 160, 98, 149, 206, 135, 11, 7, 2, 155, 252,
219, 45, 206, 40, 217, 89, 242, 129, 91, 22, 248, 23, 152,
];
let point = Point::<_, Public, NonZero>::from_bytes(bytes).unwrap();
assert_eq!(point, *G);
sourcepub fn from_slice(slice: &[u8]) -> Option<Self>
pub fn from_slice(slice: &[u8]) -> Option<Self>
Convenience method for calling from_bytes
wth a slice.
Returns None if from_bytes
would or if slice
is not 33 bytes long.
source§impl<T, S> Point<T, S, NonZero>
impl<T, S> Point<T, S, NonZero>
sourcepub fn into_point_with_even_y(self) -> (Point<EvenY, S, NonZero>, bool)where
T: PointType,
pub fn into_point_with_even_y(self) -> (Point<EvenY, S, NonZero>, bool)where
T: PointType,
Converts this point into the point with the same x-coordinate but with
an even y-coordinate. Returns a Point marked EvenY
with a bool
indicating whether the point had to be negated to make its y-coordinate
even.
§Examples
use secp256kfun::{marker::*, Point};
let point = Point::random(&mut rand::thread_rng());
let (point_with_even_y, was_odd) = point.clone().into_point_with_even_y();
sourcepub fn generator() -> Selfwhere
T: Default,
pub fn generator() -> Selfwhere
T: Default,
Returns the generator point G
defined in Standards for Efficient Cryptography.
This is sometimes more useful than just using secp256kfun::G
since it allows the compiler
to infer types.
§Examples
use secp256kfun::{marker::*, Point, G};
assert_eq!(Point::<Normal, Public, _>::generator(), *G);
source§impl Point<EvenY, Public, NonZero>
impl Point<EvenY, Public, NonZero>
sourcepub fn even_y_from_scalar_mul(
base: &Point<impl PointType, impl Secrecy>,
scalar: &mut Scalar<impl Secrecy>
) -> Self
pub fn even_y_from_scalar_mul( base: &Point<impl PointType, impl Secrecy>, scalar: &mut Scalar<impl Secrecy> ) -> Self
Multiplies base
by scalar
and returns the resulting point. If the
resulting point does not have an even y-coordinate then the scalar and
point are negated so the point has an even y-coordinate and the scalar
matches it.
§Examples
use secp256kfun::{marker::*, Point, Scalar, G};
let mut secret_key = Scalar::random(&mut rand::thread_rng());
let public_key = Point::even_y_from_scalar_mul(G, &mut secret_key);
assert!(public_key.is_y_even());
source§impl<T, S, Z> Point<T, S, Z>
impl<T, S, Z> Point<T, S, Z>
sourcepub fn is_zero(&self) -> bool
pub fn is_zero(&self) -> bool
Returns true if this point the [identity element
] of the group A.K.A. the point at infinity.
§Examples
let point = Point::random(&mut rand::thread_rng());
assert!(!point.is_zero());
assert!(g!(0 * point).is_zero());
sourcepub fn conditional_negate(&self, cond: bool) -> Point<T::NegationType, S, Z>where
T: PointType,
pub fn conditional_negate(&self, cond: bool) -> Point<T::NegationType, S, Z>where
T: PointType,
Negates a point based on a condition.
If cond
is true the value returned is the negation of the point, otherwise it will be the point.
sourcepub fn set_secrecy<SNew>(self) -> Point<T, SNew, Z>
pub fn set_secrecy<SNew>(self) -> Point<T, SNew, Z>
Set the Secrecy
of the point.
sourcepub fn non_normal(self) -> Point<NonNormal, S, Z>
pub fn non_normal(self) -> Point<NonNormal, S, Z>
Mark the point as being NonNormal
.
This is sometimes helpful when you have an accumulater variable where although the first
value of the point is normalized the subsequent values will not be so to satisfy the
compiler you have to set it to NonNormal
before you start.
sourcepub fn mark_zero(self) -> Point<T, S, Zero>
pub fn mark_zero(self) -> Point<T, S, Zero>
Mark the point as possibly being Zero
(even though it isn’t).
This is useful in accumulator variables where although the initial value is non-zero, every
sum addition after that might make it zero so it’s necessary to start off with Zero
marked
point.
source§impl<Z, T> Point<T, Public, Z>
impl<Z, T> Point<T, Public, Z>
sourcepub fn x_eq_scalar<Z2>(&self, scalar: &Scalar<Public, Z2>) -> bool
pub fn x_eq_scalar<Z2>(&self, scalar: &Scalar<Public, Z2>) -> bool
Checks if this point’s x-coordiante is the equal to the scalar mod the curve order. This is only useful for ECDSA implementations.
source§impl<S, Z, T: Normalized> Point<T, S, Z>
impl<S, Z, T: Normalized> Point<T, S, Z>
sourcepub fn to_bytes(&self) -> [u8; 33]
pub fn to_bytes(&self) -> [u8; 33]
Converts the point to its compressed encoding as specified by Standards for Efficient Cryptography.
§Example
Round trip serialization with from_bytes
use secp256kfun::{marker::*, Point};
let point = Point::random(&mut rand::thread_rng());
let bytes = point.to_bytes();
assert!(bytes[0] == 0x02 || bytes[0] == 0x03);
assert_eq!(
Point::<_, Public, NonZero>::from_bytes(bytes).unwrap(),
point
);
source§impl<S> Point<EvenY, S, NonZero>
impl<S> Point<EvenY, S, NonZero>
sourcepub fn from_xonly_bytes(bytes: [u8; 32]) -> Option<Self>
pub fn from_xonly_bytes(bytes: [u8; 32]) -> Option<Self>
Creates a point with EvenY
from 32 byte x-coordinate
source§impl<T, S> Point<T, S, Zero>
impl<T, S> Point<T, S, Zero>
sourcepub fn non_zero(self) -> Option<Point<T, S, NonZero>>
pub fn non_zero(self) -> Option<Point<T, S, NonZero>>
Convert a point that is marked as Zero
to NonZero
.
If the point was actually zero (is_zero
returns true) it returns None
.
sourcepub fn zero() -> Selfwhere
T: Default,
pub fn zero() -> Selfwhere
T: Default,
Returns the [identity element
] of the group A.K.A. the point at infinity.
§Example
use secp256kfun::{g, marker::*, s, Point, G};
let zero = Point::<Normal, Public, _>::zero();
assert!(zero.is_zero());
assert_eq!(g!(zero + G), *G);
assert_eq!(zero, g!(0 * G))
source§impl<S, T: Normalized> Point<T, S, NonZero>
impl<S, T: Normalized> Point<T, S, NonZero>
sourcepub fn coordinates(&self) -> ([u8; 32], [u8; 32])
pub fn coordinates(&self) -> ([u8; 32], [u8; 32])
Returns the x and y coordinates of the point as two 32-byte arrays containing their big endian encoding.
§Example
let point = Point::random(&mut rand::thread_rng());
let (x_coord, y_coord) = point.coordinates();
sourcepub fn to_xonly_bytes(&self) -> [u8; 32]
pub fn to_xonly_bytes(&self) -> [u8; 32]
Serializes a point with EvenY
to its 32-byte x-coordinate
sourcepub fn to_bytes_uncompressed(&self) -> [u8; 65]
pub fn to_bytes_uncompressed(&self) -> [u8; 65]
Encodes a point as its compressed encoding as specified by Standards for Efficient Cryptography.
§Example
use secp256kfun::{marker::*, Point};
let point = Point::random(&mut rand::thread_rng());
let bytes = point.to_bytes_uncompressed();
assert_eq!(Point::from_bytes_uncompressed(bytes).unwrap(), point);
Trait Implementations§
source§impl<TR, SL, SR, ZR> AddAssign<&Point<TR, SR, ZR>> for Point<NonNormal, SL, Zero>
impl<TR, SL, SR, ZR> AddAssign<&Point<TR, SR, ZR>> for Point<NonNormal, SL, Zero>
source§fn add_assign(&mut self, rhs: &Point<TR, SR, ZR>)
fn add_assign(&mut self, rhs: &Point<TR, SR, ZR>)
+=
operation. Read moresource§impl<TR, SL, SR, ZR> AddAssign<Point<TR, SR, ZR>> for Point<NonNormal, SL, Zero>
impl<TR, SL, SR, ZR> AddAssign<Point<TR, SR, ZR>> for Point<NonNormal, SL, Zero>
source§fn add_assign(&mut self, rhs: Point<TR, SR, ZR>)
fn add_assign(&mut self, rhs: Point<TR, SR, ZR>)
+=
operation. Read moresource§impl<S: Secrecy> Arbitrary for Point<EvenY, S, NonZero>
impl<S: Secrecy> Arbitrary for Point<EvenY, S, NonZero>
§type Parameters = ()
type Parameters = ()
arbitrary_with
accepts for configuration
of the generated Strategy
. Parameters must implement Default
.§type Strategy = BoxedStrategy<Point<EvenY, S>>
type Strategy = BoxedStrategy<Point<EvenY, S>>
Strategy
used to generate values of type Self
.source§fn arbitrary_with(_: Self::Parameters) -> Self::Strategy
fn arbitrary_with(_: Self::Parameters) -> Self::Strategy
source§impl<S: Secrecy> Arbitrary for Point<NonNormal, S, NonZero>
impl<S: Secrecy> Arbitrary for Point<NonNormal, S, NonZero>
§type Parameters = ()
type Parameters = ()
arbitrary_with
accepts for configuration
of the generated Strategy
. Parameters must implement Default
.§type Strategy = BoxedStrategy<Point<NonNormal, S>>
type Strategy = BoxedStrategy<Point<NonNormal, S>>
Strategy
used to generate values of type Self
.source§fn arbitrary_with(_: Self::Parameters) -> Self::Strategy
fn arbitrary_with(_: Self::Parameters) -> Self::Strategy
source§impl<S: Secrecy> Arbitrary for Point<NonNormal, S, Zero>
impl<S: Secrecy> Arbitrary for Point<NonNormal, S, Zero>
§type Parameters = ()
type Parameters = ()
arbitrary_with
accepts for configuration
of the generated Strategy
. Parameters must implement Default
.§type Strategy = BoxedStrategy<Point<NonNormal, S, Zero>>
type Strategy = BoxedStrategy<Point<NonNormal, S, Zero>>
Strategy
used to generate values of type Self
.source§fn arbitrary_with(_: Self::Parameters) -> Self::Strategy
fn arbitrary_with(_: Self::Parameters) -> Self::Strategy
source§impl<S: Secrecy> Arbitrary for Point<Normal, S, NonZero>
impl<S: Secrecy> Arbitrary for Point<Normal, S, NonZero>
§type Parameters = ()
type Parameters = ()
arbitrary_with
accepts for configuration
of the generated Strategy
. Parameters must implement Default
.§type Strategy = BoxedStrategy<Point<Normal, S>>
type Strategy = BoxedStrategy<Point<Normal, S>>
Strategy
used to generate values of type Self
.source§fn arbitrary_with(_: Self::Parameters) -> Self::Strategy
fn arbitrary_with(_: Self::Parameters) -> Self::Strategy
source§impl<S: Secrecy> Arbitrary for Point<Normal, S, Zero>
impl<S: Secrecy> Arbitrary for Point<Normal, S, Zero>
§type Parameters = ()
type Parameters = ()
arbitrary_with
accepts for configuration
of the generated Strategy
. Parameters must implement Default
.§type Strategy = BoxedStrategy<Point<Normal, S, Zero>>
type Strategy = BoxedStrategy<Point<Normal, S, Zero>>
Strategy
used to generate values of type Self
.source§fn arbitrary_with(_: Self::Parameters) -> Self::Strategy
fn arbitrary_with(_: Self::Parameters) -> Self::Strategy
source§impl<'de, S> BorrowDecode<'de> for Point<EvenY, S, NonZero>
Available on crate feature bincode
only.
impl<'de, S> BorrowDecode<'de> for Point<EvenY, S, NonZero>
bincode
only.source§fn borrow_decode<D: BorrowDecoder<'de>>(
decoder: &mut D
) -> Result<Self, DecodeError>
fn borrow_decode<D: BorrowDecoder<'de>>( decoder: &mut D ) -> Result<Self, DecodeError>
source§impl<'de, S, Z: ZeroChoice> BorrowDecode<'de> for Point<Normal, S, Z>
Available on crate feature bincode
only.
impl<'de, S, Z: ZeroChoice> BorrowDecode<'de> for Point<Normal, S, Z>
bincode
only.source§fn borrow_decode<D: BorrowDecoder<'de>>(
decoder: &mut D
) -> Result<Self, DecodeError>
fn borrow_decode<D: BorrowDecoder<'de>>( decoder: &mut D ) -> Result<Self, DecodeError>
source§impl<T: Default, S, Z> ConditionallySelectable for Point<T, S, Z>where
Self: Copy,
impl<T: Default, S, Z> ConditionallySelectable for Point<T, S, Z>where
Self: Copy,
source§impl<S, Z: ZeroChoice> Decode for Point<Normal, S, Z>
Available on crate feature bincode
only.
impl<S, Z: ZeroChoice> Decode for Point<Normal, S, Z>
bincode
only.source§impl<T: Default + PointType, S> Default for Point<T, S, NonZero>
impl<T: Default + PointType, S> Default for Point<T, S, NonZero>
The default for Point
<,,Zero> is [
Point::generator`].
source§impl<T: Default, S> Default for Point<T, S, Zero>
impl<T: Default, S> Default for Point<T, S, Zero>
The default for Point
<,,Zero> is [
Point::zero`].
source§impl<'de, S> Deserialize<'de> for Point<EvenY, S, NonZero>
Available on crate feature serde
only.
impl<'de, S> Deserialize<'de> for Point<EvenY, S, NonZero>
serde
only.source§fn deserialize<Deser: Deserializer<'de>>(
deserializer: Deser
) -> Result<Point<EvenY, S, NonZero>, Deser::Error>
fn deserialize<Deser: Deserializer<'de>>( deserializer: Deser ) -> Result<Point<EvenY, S, NonZero>, Deser::Error>
source§impl<'de, S, Z: ZeroChoice> Deserialize<'de> for Point<Normal, S, Z>
Available on crate feature serde
only.
impl<'de, S, Z: ZeroChoice> Deserialize<'de> for Point<Normal, S, Z>
serde
only.source§fn deserialize<Deser: Deserializer<'de>>(
deserializer: Deser
) -> Result<Point<Normal, S, Z>, Deser::Error>
fn deserialize<Deser: Deserializer<'de>>( deserializer: Deser ) -> Result<Point<Normal, S, Z>, Deser::Error>
source§impl From<XOnlyPublicKey> for Point<EvenY>
impl From<XOnlyPublicKey> for Point<EvenY>
source§fn from(pk: XOnlyPublicKey) -> Self
fn from(pk: XOnlyPublicKey) -> Self
source§impl From<XOnlyPublicKey> for Point<EvenY>
impl From<XOnlyPublicKey> for Point<EvenY>
source§fn from(pk: XOnlyPublicKey) -> Self
fn from(pk: XOnlyPublicKey) -> Self
source§impl<T1: Normalized, Z1> Ord for Point<T1, Public, Z1>
impl<T1: Normalized, Z1> Ord for Point<T1, Public, Z1>
1.21.0 · source§fn max(self, other: Self) -> Selfwhere
Self: Sized,
fn max(self, other: Self) -> Selfwhere
Self: Sized,
source§impl<T1, S1, Z1, T2, S2, Z2> PartialEq<Point<T2, S2, Z2>> for Point<T1, S1, Z1>
impl<T1, S1, Z1, T2, S2, Z2> PartialEq<Point<T2, S2, Z2>> for Point<T1, S1, Z1>
source§impl<T1: Normalized, Z1, T2: Normalized, Z2> PartialOrd<Point<T2, Public, Z2>> for Point<T1, Public, Z1>
impl<T1: Normalized, Z1, T2: Normalized, Z2> PartialOrd<Point<T2, Public, Z2>> for Point<T1, Public, Z1>
1.0.0 · source§fn le(&self, other: &Rhs) -> bool
fn le(&self, other: &Rhs) -> bool
self
and other
) and is used by the <=
operator. Read moresource§impl<TR, SL, SR, ZR> SubAssign<&Point<TR, SR, ZR>> for Point<NonNormal, SL, Zero>
impl<TR, SL, SR, ZR> SubAssign<&Point<TR, SR, ZR>> for Point<NonNormal, SL, Zero>
source§fn sub_assign(&mut self, rhs: &Point<TR, SR, ZR>)
fn sub_assign(&mut self, rhs: &Point<TR, SR, ZR>)
-=
operation. Read moresource§impl<TR, SL, SR, ZR> SubAssign<Point<TR, SR, ZR>> for Point<NonNormal, SL, Zero>
impl<TR, SL, SR, ZR> SubAssign<Point<TR, SR, ZR>> for Point<NonNormal, SL, Zero>
source§fn sub_assign(&mut self, rhs: Point<TR, SR, ZR>)
fn sub_assign(&mut self, rhs: Point<TR, SR, ZR>)
-=
operation. Read more