[−][src]Struct bls_like::single::SecretKey
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:
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?
Methods
impl<E: EngineBLS> SecretKey<E>
[src]
pub fn init_point_mutation<R: Rng>(&mut self, rng: R)
[src]
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.
pub fn generate_dirty<R: Rng>(rng: R) -> Self
[src]
Generate a secret key that is already split for side channel protection, but does not apply signed point mutation.
pub fn generate<R: Rng>(rng: R) -> Self
[src]
Generate a secret key that is already split for side channel protection.
pub fn into_vartime(&self) -> SecretKeyVT<E>
[src]
Create a representative usable for operations lacking side channel protections.
pub fn resplit<R: Rng>(&mut self, rng: R)
[src]
Randomly adjust how we split our secret signing key.
pub fn sign_once(&mut self, message: Message) -> Signature<E>
[src]
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.
pub fn sign<R: Rng>(&mut self, message: Message, rng: R) -> Signature<E>
[src]
Sign after respliting the secret key for side channel protections.
pub fn into_public(&self) -> PublicKey<E>
[src]
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
Auto Trait Implementations
impl<E> Sync for SecretKey<E> where
<E as EngineBLS>::Scalar: Sync,
<E as EngineBLS>::SignatureGroup: Sync,
<E as EngineBLS>::Scalar: Sync,
<E as EngineBLS>::SignatureGroup: Sync,
impl<E> Send for SecretKey<E> where
<E as EngineBLS>::Scalar: Send,
<E as EngineBLS>::SignatureGroup: Send,
<E as EngineBLS>::Scalar: Send,
<E as EngineBLS>::SignatureGroup: Send,
impl<E> Unpin for SecretKey<E> where
<E as EngineBLS>::Scalar: Unpin,
<E as EngineBLS>::SignatureGroup: Unpin,
<E as EngineBLS>::Scalar: Unpin,
<E as EngineBLS>::SignatureGroup: Unpin,
impl<E> RefUnwindSafe for SecretKey<E> where
<E as EngineBLS>::Scalar: RefUnwindSafe,
<E as EngineBLS>::SignatureGroup: RefUnwindSafe,
<E as EngineBLS>::Scalar: RefUnwindSafe,
<E as EngineBLS>::SignatureGroup: RefUnwindSafe,
impl<E> UnwindSafe for SecretKey<E> where
<E as EngineBLS>::Scalar: UnwindSafe,
<E as EngineBLS>::SignatureGroup: UnwindSafe,
<E as EngineBLS>::Scalar: UnwindSafe,
<E as EngineBLS>::SignatureGroup: UnwindSafe,
Blanket Implementations
impl<T> ToOwned for T where
T: Clone,
[src]
T: Clone,
type Owned = T
The resulting type after obtaining ownership.
fn to_owned(&self) -> T
[src]
fn clone_into(&self, target: &mut T)
[src]
impl<T, U> Into<U> for T where
U: From<T>,
[src]
U: From<T>,
impl<T> From<T> for T
[src]
impl<T, U> TryFrom<U> for T where
U: Into<T>,
[src]
U: Into<T>,
type Error = Infallible
The type returned in the event of a conversion error.
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
[src]
impl<T, U> TryInto<U> for T where
U: TryFrom<T>,
[src]
U: TryFrom<T>,
type Error = <U as TryFrom<T>>::Error
The type returned in the event of a conversion error.
fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>
[src]
impl<T> BorrowMut<T> for T where
T: ?Sized,
[src]
T: ?Sized,
fn borrow_mut(&mut self) -> &mut T
[src]
impl<T> Borrow<T> for T where
T: ?Sized,
[src]
T: ?Sized,
impl<T> Any for T where
T: 'static + ?Sized,
[src]
T: 'static + ?Sized,
impl<T> Same<T> for T
type Output = T
Should always be Self