Struct secp256kfun::Scalar
source · pub struct Scalar<S = Secret, Z = NonZero>(/* private fields */);
Expand description
A secp256k1 scalar (an integer mod the curve order)
The term scalar comes from interpreting the secp256k1 elliptic curve group
as a vector space with a point as a notional single element vector
and the field of integers modulo the curve order as its
scalars. Specifically, a Scalar
represents an integer modulo the curve
order q
where
q = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141
The thing that makes secp256k1 and other elliptic curves useful for cryptography is that scalar multiplication can be done efficiently:
use secp256kfun::{g, Scalar, G};
let x = Scalar::random(&mut rand::thread_rng());
let X = g!(x * G);
But finding x
from (X,G)
is hard because there is no known efficient
algorithm to divide X
by G
to get x
. This is known as the elliptic
curve discrete logarithm problem. Because of this, scalars are often
used as a secret keys with the points obtained by multiplying them by G
as
their corresponding public keys.
§Markers
A Scalar<S,Z>
has two markers:
S
: ASecrecy
to determine whether operations on this scalar should be done in constant time or not. By default scalars areSecret
so operations run in constant-time.Z
: AZeroChoice
to keep track of whether the point might be zero or is guaranteed to non-zero.
Implementations§
source§impl<Z, S> Scalar<S, Z>
impl<Z, S> Scalar<S, Z>
sourcepub fn to_bytes(&self) -> [u8; 32]
pub fn to_bytes(&self) -> [u8; 32]
Serializes the scalar to its 32-byte big-endian representation
sourcepub fn from_bytes(bytes: [u8; 32]) -> Option<Self>where
Z: ZeroChoice,
pub fn from_bytes(bytes: [u8; 32]) -> Option<Self>where
Z: ZeroChoice,
Creates a scalar from 32 big-endian encoded bytes. If the bytes represent an integer greater
than or equal to the curve order then it returns None
. If the scalar is marked NonZero
then it will also return None
it it’s the zero scalar.
§Example
use secp256kfun::{marker::*, Scalar};
assert!(Scalar::<Secret, Zero>::from_bytes([0u8; 32]).is_some());
// NonZero scalar's can't be zero
assert!(Scalar::<Secret, NonZero>::from_bytes([0u8; 32]).is_none());
// >= curve order
assert!(Scalar::<Secret, Zero>::from_bytes([255u8; 32]).is_none());
sourcepub fn from_slice(slice: &[u8]) -> Option<Self>where
Z: ZeroChoice,
pub fn from_slice(slice: &[u8]) -> Option<Self>where
Z: ZeroChoice,
Decode a 32 byte long slice to a scalar.
Essentially from_bytes
but checks that the slice is 32
bytes long first.
sourcepub fn conditional_negate(&mut self, cond: bool)
pub fn conditional_negate(&mut self, cond: bool)
Negates the scalar in-place if cond
is true.
sourcepub fn set_secrecy<SNew>(self) -> Scalar<SNew, Z>
pub fn set_secrecy<SNew>(self) -> Scalar<SNew, Z>
Set the secrecy of the Scalar
to the type parameter.
sourcepub fn public(self) -> Scalar<Public, Z>
pub fn public(self) -> Scalar<Public, Z>
Set the secrecy of the Scalar to Public
.
A scalar should be set to public when the adversary is meant to know it as part of the protocol.
sourcepub fn secret(self) -> Scalar<Secret, Z>
pub fn secret(self) -> Scalar<Secret, Z>
Set the secrecy of the Scalar to Secret
.
A scalar should be set to secret when the adversary is not meant to know about it in the protocol.
sourcepub fn mark_zero(self) -> Scalar<S, Zero>
pub fn mark_zero(self) -> Scalar<S, Zero>
Mark the scalar 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
scalar.
source§impl<S> Scalar<S, NonZero>
impl<S> Scalar<S, NonZero>
sourcepub fn invert(&self) -> Self
pub fn invert(&self) -> Self
Returns the multiplicative inverse of the scalar modulo the curve order.
§Example
use secp256kfun::{marker::*, s, Scalar};
let a = Scalar::random(&mut rand::thread_rng());
let a_inverse = a.invert();
assert_eq!(s!(a * a_inverse), s!(1));
sourcepub fn mark_zero_choice<Z: ZeroChoice>(self) -> Scalar<S, Z>
pub fn mark_zero_choice<Z: ZeroChoice>(self) -> Scalar<S, Z>
Marks a scalar non-zero scalar as having the zero choice Z
(rather than NonZero
).
Useful when writing code that preserves the zero choice of the caller.
§Example
use secp256kfun::{marker::*, s, Scalar};
/// Returns an iterator of 1, x, x², x³ ...
fn powers<S: Secrecy, Z: ZeroChoice>(x: Scalar<S, Z>) -> impl Iterator<Item = Scalar<S, Z>> {
core::iter::successors(Some(Scalar::one().mark_zero_choice::<Z>()), move |xpow| {
Some(s!(xpow * x).set_secrecy())
})
}
assert_eq!(powers(s!(2)).take(4).collect::<Vec<_>>(), vec![
s!(1),
s!(2),
s!(4),
s!(8)
]);
assert_eq!(powers(s!(0)).take(4).collect::<Vec<_>>(), vec![
s!(1).mark_zero(),
s!(0),
s!(0),
s!(0)
]);
source§impl Scalar<Secret, NonZero>
impl Scalar<Secret, NonZero>
sourcepub fn random<R: RngCore>(rng: &mut R) -> Self
pub fn random<R: RngCore>(rng: &mut R) -> Self
Generates a random scalar from randomness taken from a caller provided cryptographically secure random number generator.
§Example
use secp256kfun::{g, Scalar, G};
let secret_scalar = Scalar::random(&mut rand::thread_rng());
let public_point = g!(secret_scalar * G);
sourcepub fn from_hash(hash: impl Digest<OutputSize = U32>) -> Self
pub fn from_hash(hash: impl Digest<OutputSize = U32>) -> Self
Converts the output of a 32-byte hash into a scalar by reducing it modulo the curve order.
§Example
use digest::Digest;
use secp256kfun::Scalar;
let mut hash = sha2::Sha256::default();
hash.update(b"Chancellor on brink of second bailout for banks".as_ref());
let scalar = Scalar::from_hash(hash);
sourcepub fn from_non_zero_u32(int: NonZeroU32) -> Self
pub fn from_non_zero_u32(int: NonZeroU32) -> Self
Converts a NonZeroU32
into a Scalar<Secret,NonZero>
.
source§impl<S> Scalar<S, Zero>
impl<S> Scalar<S, Zero>
sourcepub fn non_zero(self) -> Option<Scalar<S, NonZero>>
pub fn non_zero(self) -> Option<Scalar<S, NonZero>>
Converts a scalar marked with Zero
to NonZero
.
Returns None
in the case that the scalar was in fact zero.
sourcepub fn zero() -> Self
pub fn zero() -> Self
Returns the zero scalar.
§Example
let x = Scalar::random(&mut rand::thread_rng());
let zero = Scalar::<Secret,_>::zero();
assert_eq!(s!(zero * x), zero);
assert_eq!(s!(x + zero), x);
sourcepub fn from_bytes_mod_order(bytes: [u8; 32]) -> Self
pub fn from_bytes_mod_order(bytes: [u8; 32]) -> Self
Converts 32 bytes into a scalar by reducing it modulo the curve order q
.
§Example
use secp256kfun::{hex, marker::*, s, Scalar};
let scalar = Scalar::<Secret, _>::from_bytes_mod_order(*b"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
assert_eq!(scalar.to_bytes(), *b"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
let scalar_overflowed = Scalar::<Secret, _>::from_bytes_mod_order(
hex::decode_array("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364142")
.unwrap(),
);
assert_eq!(scalar_overflowed, s!(1))
sourcepub fn from_slice_mod_order(slice: &[u8]) -> Option<Self>
pub fn from_slice_mod_order(slice: &[u8]) -> Option<Self>
Exactly like from_bytes_mod_order
except
it operates on a 32-byte slice rather than an array. If the slice is
not 32 bytes long then the function returns None
.
§Example
use secp256kfun::{marker::*, Scalar};
let bytes = b"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
assert!(Scalar::<Secret, _>::from_slice_mod_order(&bytes[..31]).is_none());
assert_eq!(
Scalar::<Secret, _>::from_slice_mod_order(&bytes[..]).unwrap(),
Scalar::<Secret, _>::from_bytes_mod_order(*bytes)
);
Trait Implementations§
source§impl<SL, SR, ZR> AddAssign<&Scalar<SR, ZR>> for Scalar<SL, Zero>
impl<SL, SR, ZR> AddAssign<&Scalar<SR, ZR>> for Scalar<SL, Zero>
source§fn add_assign(&mut self, rhs: &Scalar<SR, ZR>)
fn add_assign(&mut self, rhs: &Scalar<SR, ZR>)
+=
operation. Read moresource§impl<SL, SR, ZR> AddAssign<Scalar<SR, ZR>> for Scalar<SL, Zero>
impl<SL, SR, ZR> AddAssign<Scalar<SR, ZR>> for Scalar<SL, Zero>
source§fn add_assign(&mut self, rhs: Scalar<SR, ZR>)
fn add_assign(&mut self, rhs: Scalar<SR, ZR>)
+=
operation. Read moresource§impl<S: Secrecy> Arbitrary for Scalar<S, NonZero>
impl<S: Secrecy> Arbitrary for Scalar<S, NonZero>
§type Parameters = ()
type Parameters = ()
arbitrary_with
accepts for configuration
of the generated Strategy
. Parameters must implement Default
.§type Strategy = BoxedStrategy<Scalar<S>>
type Strategy = BoxedStrategy<Scalar<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 Scalar<S, Zero>
impl<S: Secrecy> Arbitrary for Scalar<S, Zero>
§type Parameters = ()
type Parameters = ()
arbitrary_with
accepts for configuration
of the generated Strategy
. Parameters must implement Default
.§type Strategy = BoxedStrategy<Scalar<S, Zero>>
type Strategy = BoxedStrategy<Scalar<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, Z: ZeroChoice> BorrowDecode<'de> for Scalar<S, Z>
Available on crate feature bincode
only.
impl<'de, S, Z: ZeroChoice> BorrowDecode<'de> for Scalar<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<S, Z: ZeroChoice> Decode for Scalar<S, Z>
Available on crate feature bincode
only.
impl<S, Z: ZeroChoice> Decode for Scalar<S, Z>
bincode
only.source§impl<'de, S, Z: ZeroChoice> Deserialize<'de> for Scalar<S, Z>
Available on crate feature serde
only.
impl<'de, S, Z: ZeroChoice> Deserialize<'de> for Scalar<S, Z>
serde
only.source§fn deserialize<Deser: Deserializer<'de>>(
deserializer: Deser
) -> Result<Scalar<S, Z>, Deser::Error>
fn deserialize<Deser: Deserializer<'de>>( deserializer: Deser ) -> Result<Scalar<S, Z>, Deser::Error>
source§impl<S, Z: ZeroChoice> FromStr for Scalar<S, Z>
impl<S, Z: ZeroChoice> FromStr for Scalar<S, Z>
source§impl<SL, SR, ZR: ZeroChoice> MulAssign<&Scalar<SR, ZR>> for Scalar<SL, Zero>
impl<SL, SR, ZR: ZeroChoice> MulAssign<&Scalar<SR, ZR>> for Scalar<SL, Zero>
source§fn mul_assign(&mut self, rhs: &Scalar<SR, ZR>)
fn mul_assign(&mut self, rhs: &Scalar<SR, ZR>)
*=
operation. Read moresource§impl<SL, SR, ZR: ZeroChoice> MulAssign<Scalar<SR, ZR>> for Scalar<SL, Zero>
impl<SL, SR, ZR: ZeroChoice> MulAssign<Scalar<SR, ZR>> for Scalar<SL, Zero>
source§fn mul_assign(&mut self, rhs: Scalar<SR, ZR>)
fn mul_assign(&mut self, rhs: Scalar<SR, ZR>)
*=
operation. Read moresource§impl<Z> Ord for Scalar<Public, Z>
impl<Z> Ord for Scalar<Public, Z>
source§impl<Z1, Z2, S1, S2> PartialEq<Scalar<S2, Z2>> for Scalar<S1, Z1>
impl<Z1, Z2, S1, S2> PartialEq<Scalar<S2, Z2>> for Scalar<S1, Z1>
source§impl<Z1, Z2> PartialOrd<Scalar<Public, Z2>> for Scalar<Public, Z1>
impl<Z1, Z2> PartialOrd<Scalar<Public, Z2>> for Scalar<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<SL, SR, ZR> SubAssign<&Scalar<SR, ZR>> for Scalar<SL, Zero>
impl<SL, SR, ZR> SubAssign<&Scalar<SR, ZR>> for Scalar<SL, Zero>
source§fn sub_assign(&mut self, rhs: &Scalar<SR, ZR>)
fn sub_assign(&mut self, rhs: &Scalar<SR, ZR>)
-=
operation. Read moresource§impl<SL, SR, ZR> SubAssign<Scalar<SR, ZR>> for Scalar<SL, Zero>
impl<SL, SR, ZR> SubAssign<Scalar<SR, ZR>> for Scalar<SL, Zero>
source§fn sub_assign(&mut self, rhs: Scalar<SR, ZR>)
fn sub_assign(&mut self, rhs: Scalar<SR, ZR>)
-=
operation. Read more