pub struct SecretKey<E: EngineBLS> { /* private fields */ }
Expand description
Secret signing key that is split to provide side channel protection.
A simple key splitting works because
self.key[0] * H(message) + self.key[1] * H(message) = (self.key[0] + self.key[1]) * H(message)
.
In our case, we mutate the point being signed too by keeping
an old point in both signed and unsigned forms, so our message
point becomes new_unsigned = H(message) - old_unsigned
,
we compute new_signed = self.key[0] * new_unsigned + self.key[1] * new_unsigned
,
and our signature becomes new_signed + old_signed
.
We save the new signed and unsigned values as old ones, so that adversaries
also cannot know the curves points being multiplied by scalars.
In this, our init_point_mutation
method signs some random point,
so that even an adversary who tracks all signed messages cannot
foresee the curve points being signed.
/// We require mutable access to the secret key, but interior mutability
/// can easily be employed, which might resemble:
/// rust,no_run /// # extern crate bls_like as bls; /// # extern crate rand; /// # use bls::{SecretKey,ZBLS,Message}; /// # #[cfg(feature=std)] /// # use rand::thread_rng; /// # let message = Message::new(b"ctx",b"test message"); /// let mut secret = ::std::cell::RefCell::new(SecretKey::<ZBLS>::generate(thread_rng())); /// let signature = secret.borrow_mut().sign(message,thread_rng()); ///
/// If however secret: Mutex<SecretKey>
or secret: RwLock<SecretKey>
/// then one might avoid holding the write lock while signing, or even
/// while sampling the random numbers by using other methods.
Right now, we serialize using SecretKey::into_vartime
and
SecretKeyVT::write
, so secret.into_vartime().write(writer)?
.
We deserialize using the read
, from_repr
, and into_split
methods of SecretKeyVT
, so roughly
SecretKeyVT::from_repr(SecretKeyVT::read(reader) ?) ?.into_split(thread_rng())
.
TODO: Provide sensible to_bytes
and from_bytes
methods
for ZBLS
and TinyBLS<..>
.
TODO: Is Pippenger’s algorithm, or another fast MSM algorithm, secure when used with key splitting? Secret signing key including the side channel protections from key splitting.
Implementations§
Source§impl<E> SecretKey<E>where
E: EngineBLS,
impl<E> SecretKey<E>where
E: EngineBLS,
Sourcepub fn generate_dirty<R: Rng>(rng: R) -> Self
pub fn generate_dirty<R: Rng>(rng: R) -> Self
Generate a secret key that is already split for side channel protection, but does not apply signed point mutation.
Sourcepub fn generate<R: Rng>(rng: R) -> Self
pub fn generate<R: Rng>(rng: R) -> Self
Generate a secret key that is already split for side channel protection.
pub fn from_seed(seed: &[u8]) -> Self
Source§impl<E: EngineBLS> SecretKey<E>
impl<E: EngineBLS> SecretKey<E>
Sourcepub fn init_point_mutation<R: Rng>(&mut self, rng: R)
pub fn init_point_mutation<R: Rng>(&mut self, rng: R)
Initialize the signature curve signed point mutation.
Amortized over many signings involing this once costs nothing, but each individual invokation costs as much as signing.
Sourcepub fn into_vartime(&self) -> SecretKeyVT<E>
pub fn into_vartime(&self) -> SecretKeyVT<E>
Create a representative usable for operations lacking side channel protections.
Sourcepub fn sign_once(&mut self, message: &Message) -> Signature<E>
pub fn sign_once(&mut self, message: &Message) -> Signature<E>
Sign without doing the key resplit mutation that provides side channel protection.
Avoid using directly without appropriate replit
calls, but maybe
useful in proof-of-concenpt code, as it does not require a mutable
secret key.
Sourcepub fn sign<R: Rng>(&mut self, message: &Message, rng: R) -> Signature<E>
pub fn sign<R: Rng>(&mut self, message: &Message, rng: R) -> Signature<E>
Sign after respliting the secret key for side channel protections.
Sourcepub fn into_public(&self) -> PublicKey<E>
pub fn into_public(&self) -> PublicKey<E>
Derive our public key from our secret key
We do not resplit for side channel protections here since this call should be rare.
Trait Implementations§
Source§impl<E> CanonicalDeserialize for SecretKey<E>where
E: EngineBLS,
impl<E> CanonicalDeserialize for SecretKey<E>where
E: EngineBLS,
Source§fn deserialize_with_mode<R: Read>(
reader: R,
compress: Compress,
validate: Validate,
) -> Result<Self, SerializationError>
fn deserialize_with_mode<R: Read>( reader: R, compress: Compress, validate: Validate, ) -> Result<Self, SerializationError>
fn deserialize_compressed<R: Read>( reader: R, ) -> Result<Self, SerializationError>
fn deserialize_uncompressed<R: Read>( reader: R, ) -> Result<Self, SerializationError>
fn deserialize_uncompressed_unchecked<R: Read>( reader: R, ) -> Result<Self, SerializationError>
fn deserialize_compressed_unchecked<R>(
reader: R,
) -> Result<Self, SerializationError>where
R: Read,
Source§impl<E> CanonicalSerialize for SecretKey<E>where
E: EngineBLS,
impl<E> CanonicalSerialize for SecretKey<E>where
E: EngineBLS,
Implementing de/serialization for secret keypair Note that deriving serialization for secret is not sensible as you need to conver them to vartime form first
Source§fn serialize_with_mode<W: Write>(
&self,
writer: W,
compress: Compress,
) -> Result<(), SerializationError>
fn serialize_with_mode<W: Write>( &self, writer: W, compress: Compress, ) -> Result<(), SerializationError>
fn serialize_compressed<W: Write>( &self, writer: W, ) -> Result<(), SerializationError>
fn serialized_size(&self, compress: Compress) -> usize
fn serialize_uncompressed<W: Write>( &self, writer: W, ) -> Result<(), SerializationError>
fn uncompressed_size(&self) -> usize
fn compressed_size(&self) -> usize
Source§impl<E: EngineBLS> SerializableToBytes for SecretKey<E>
impl<E: EngineBLS> SerializableToBytes for SecretKey<E>
const SERIALIZED_BYTES_SIZE: usize = E::SECRET_KEY_SIZE
fn to_bytes(&self) -> Vec<u8>
fn from_bytes(bytes: &[u8]) -> Result<Self, SerializationError>
Auto Trait Implementations§
impl<E> Freeze for SecretKey<E>
impl<E> RefUnwindSafe for SecretKey<E>
impl<E> Send for SecretKey<E>
impl<E> Sync for SecretKey<E>
impl<E> Unpin for SecretKey<E>
impl<E> UnwindSafe for SecretKey<E>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CanonicalSerializeHashExt for Twhere
T: CanonicalSerialize,
impl<T> CanonicalSerializeHashExt for Twhere
T: CanonicalSerialize,
fn hash<H>(&self) -> GenericArray<u8, <H as OutputSizeUser>::OutputSize>where
H: Digest,
fn hash_uncompressed<H>(
&self,
) -> GenericArray<u8, <H as OutputSizeUser>::OutputSize>where
H: Digest,
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§unsafe fn clone_to_uninit(&self, dst: *mut T)
unsafe fn clone_to_uninit(&self, dst: *mut T)
clone_to_uninit
)Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left
is true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left(&self)
returns true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read more