pub struct RsaContext { /* private fields */ }Expand description
An RSA work queue user.
This object allows performing big number multiplication, big number modular
multiplication and big number modular
exponentiation with hardware acceleration. To perform these
operations, the RsaBackend must be started, otherwise these operations will never complete.
The context is created with a secure configuration by default. You can enable hardware acceleration options using enable_search_acceleration and enable_acceleration when appropriate.
Implementations§
Source§impl RsaContext
 
impl RsaContext
Sourcepub fn enable_search_acceleration(&mut self)
 
pub fn enable_search_acceleration(&mut self)
Enables search acceleration.
When enabled it would increase the performance of modular exponentiation by discarding the exponent’s bits before the most significant set bit.
⚠️ Note: this compromises security by effectively decreasing the key length.
For more information refer to the Technical Reference Manual
Sourcepub fn enable_acceleration(&mut self)
 
pub fn enable_acceleration(&mut self)
Enables acceleration by disabling constant time operation.
Disabling constant time operation increases the performance of modular exponentiation by simplifying the calculation concerning the 0 bits of the exponent. I.e. the less the Hamming weight, the greater the performance.
⚠️ Note: this compromises security by enabling timing-based side-channel attacks.
For more information refer to the Technical Reference Manual
Sourcepub fn modular_exponentiate<'t, OP>(
    &'t mut self,
    x: &'t OP::InputType,
    y: &'t OP::InputType,
    m: &'t OP::InputType,
    r: &'t OP::InputType,
    m_prime: u32,
    result: &'t mut OP::InputType,
) -> RsaHandle<'t>where
    OP: RsaMode,
 
pub fn modular_exponentiate<'t, OP>(
    &'t mut self,
    x: &'t OP::InputType,
    y: &'t OP::InputType,
    m: &'t OP::InputType,
    r: &'t OP::InputType,
    m_prime: u32,
    result: &'t mut OP::InputType,
) -> RsaHandle<'t>where
    OP: RsaMode,
Starts a modular exponentiation operation, performing Z = X ^ Y mod M.
Software needs to pre-calculate the following values:
- r:- 2 ^ ( bitlength * 2 ) mod M.
- m_primecan be calculated using- -(modular multiplicative inverse of M) mod 2^32.
It is relatively easy to calculate these values using the crypto-bigint crate:
use crypto_bigint::{U512, Uint};
const fn compute_r(modulus: &U512) -> U512 {
    let mut d = [0_u32; U512::LIMBS * 2 + 1];
    d[d.len() - 1] = 1;
    let d = Uint::from_words(d);
    d.const_rem(&modulus.resize()).0.resize()
}
const fn compute_mprime(modulus: &U512) -> u32 {
    let m_inv = modulus.inv_mod2k(32).to_words()[0];
    (-1 * m_inv as i64 & (u32::MAX as i64)) as u32
}
// Inputs
const X: U512 = Uint::from_be_hex(
    "c7f61058f96db3bd87dbab08ab03b4f7f2f864eac249144adea6a65f97803b719d8ca980b7b3c0389c1c7c6\
   7dc353c5e0ec11f5fc8ce7f6073796cc8f73fa878",
);
const Y: U512 = Uint::from_be_hex(
    "1763db3344e97be15d04de4868badb12a38046bb793f7630d87cf100aa1c759afac15a01f3c4c83ec2d2f66\
   6bd22f71c3c1f075ec0e2cb0cb29994d091b73f51",
);
const M: U512 = Uint::from_be_hex(
    "6b6bb3d2b6cbeb45a769eaa0384e611e1b89b0c9b45a045aca1c5fd6e8785b38df7118cf5dd45b9b63d293b\
   67aeafa9ba25feb8712f188cb139b7d9b9af1c361",
);
// Values derived using the functions we defined above:
let r = compute_r(&M);
let mprime = compute_mprime(&M);
use esp_hal::rsa::{RsaContext, operand_sizes::Op512};
// Now perform the actual computation:
let mut rsa = RsaContext::new();
let mut outbuf = [0; 16];
let mut handle = rsa.modular_multiply::<Op512>(
    X.as_words(),
    Y.as_words(),
    M.as_words(),
    r.as_words(),
    mprime,
    &mut outbuf,
);
handle.wait_blocking();The calculation is done asynchronously. This function returns an RsaHandle that can be
used to poll the status of the calculation, to wait for it to finish, or to cancel the
operation (by dropping the handle).
When the operation is completed, the result will be stored in result.
Sourcepub fn modular_multiply<'t, OP>(
    &'t mut self,
    x: &'t OP::InputType,
    y: &'t OP::InputType,
    m: &'t OP::InputType,
    r: &'t OP::InputType,
    m_prime: u32,
    result: &'t mut OP::InputType,
) -> RsaHandle<'t>where
    OP: RsaMode,
 
pub fn modular_multiply<'t, OP>(
    &'t mut self,
    x: &'t OP::InputType,
    y: &'t OP::InputType,
    m: &'t OP::InputType,
    r: &'t OP::InputType,
    m_prime: u32,
    result: &'t mut OP::InputType,
) -> RsaHandle<'t>where
    OP: RsaMode,
Starts a modular multiplication operation, performing Z = X * Y mod M.
Software needs to pre-calculate the following values:
- r:- 2 ^ ( bitlength * 2 ) mod M.
- m_primecan be calculated using- -(modular multiplicative inverse of M) mod 2^32.
For an example how these values can be calculated and used, see Self::modular_exponentiate.
The calculation is done asynchronously. This function returns an RsaHandle that can be
used to poll the status of the calculation, to wait for it to finish, or to cancel the
operation (by dropping the handle).
When the operation is completed, the result will be stored in result.
Sourcepub fn multiply<'t, OP>(
    &'t mut self,
    x: &'t OP::InputType,
    y: &'t OP::InputType,
    result: &'t mut OP::OutputType,
) -> RsaHandle<'t>where
    OP: Multi,
 
pub fn multiply<'t, OP>(
    &'t mut self,
    x: &'t OP::InputType,
    y: &'t OP::InputType,
    result: &'t mut OP::OutputType,
) -> RsaHandle<'t>where
    OP: Multi,
Starts a multiplication operation, performing Z = X * Y.
The calculation is done asynchronously. This function returns an RsaHandle that can be
used to poll the status of the calculation, to wait for it to finish, or to cancel the
operation (by dropping the handle).
When the operation is completed, the result will be stored in result. The result is
twice as wide as the inputs.
§Example
// Inputs
// let x: [u32; 16] = [...];
// let y: [u32; 16] = [...];
let mut outbuf = [0; 32];
use esp_hal::rsa::{RsaContext, operand_sizes::Op512};
// Now perform the actual computation:
let mut rsa = RsaContext::new();
let mut handle = rsa.multiply::<Op512>(&x, &y, &mut outbuf);
handle.wait_blocking();