pub struct RsaContext { /* private fields */ }unstable only.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.
Implementations§
Source§impl RsaContext
impl RsaContext
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();