Jesse Braham 0064766ef2
No longer publicly expose the PeripheralClockControl struct (#817)
* No longer publicly expose the `PeripheralClockControl` struct

* Update examples as needed to get things building again

* Update CHANGELOG.md

* Address review feedback, fix a warning

* Use a critical section for all devices other than the ESP32-C6/H2, as they modify multiple registers

* Rebase and update `etm` driver to fix build errors
2023-09-26 09:07:57 -07:00

802 lines
32 KiB
Rust

//! Demonstrates the use of the ECC peripheral and compares the speed of
//! hardware-accelerated and pure software ECC.
#![no_std]
#![no_main]
use core::ops::Mul;
use crypto_bigint::{
modular::runtime_mod::{DynResidue, DynResidueParams},
Encoding,
U192,
U256,
};
use elliptic_curve::sec1::ToEncodedPoint;
use esp32c2_hal::{
ecc::{Ecc, EllipticCurve, Error},
peripherals::Peripherals,
prelude::*,
systimer::SystemTimer,
Rng,
};
use esp_backtrace as _;
use esp_println::{print, println};
use hex_literal::hex;
struct TestParams<'a> {
prime_fields: &'a [&'a [u8]],
nb_loop_mul: usize,
nb_loop_inv: usize,
}
const TEST_PARAMS_VECTOR: TestParams = TestParams {
prime_fields: &[
&hex!("fffffffffffffffffffffffffffffffeffffffffffffffff"),
&hex!("ffffffff00000001000000000000000000000000ffffffffffffffffffffffff"),
],
nb_loop_mul: 10,
nb_loop_inv: 20,
};
#[entry]
fn main() -> ! {
let peripherals = Peripherals::take();
let _system = peripherals.SYSTEM.split();
let mut rng = Rng::new(peripherals.RNG);
println!("ECC example");
let mut hw_ecc = Ecc::new(peripherals.ECC);
println!("Beginning stress tests...");
test_affine_point_multiplication(&mut hw_ecc, &mut rng);
test_finite_field_division(&mut hw_ecc, &mut rng);
test_affine_point_verification(&mut hw_ecc, &mut rng);
test_afine_point_verification_multiplication(&mut hw_ecc, &mut rng);
test_jacobian_point_multiplication(&mut hw_ecc, &mut rng);
test_jacobian_point_verification(&mut hw_ecc, &mut rng);
test_afine_point_verification_jacobian_multiplication(&mut hw_ecc, &mut rng);
println!("Finished stress tests!");
loop {}
}
fn test_affine_point_multiplication(ecc: &mut Ecc, rng: &mut Rng) {
for &prime_field in TEST_PARAMS_VECTOR.prime_fields {
print!("Beginning affine point multiplication tests over ");
match prime_field.len() {
24 => print!("secp192r1..."),
_ => print!("secp256r1..."),
};
let t1 = &mut [0_u8; 96];
let (k, x) = t1.split_at_mut(prime_field.len());
let (x, y) = x.split_at_mut(prime_field.len());
let (y, _) = y.split_at_mut(prime_field.len());
let mut delta_time = 0;
for _ in 0..TEST_PARAMS_VECTOR.nb_loop_mul {
loop {
rng.read(k).unwrap();
let is_zero = k.iter().all(|&elt| elt == 0);
let is_modulus = k.iter().zip(prime_field).all(|(&a, &b)| a == b);
if is_zero == false && is_modulus == false {
break;
}
}
let curve = match prime_field.len() {
24 => {
x.copy_from_slice(
p192::AffinePoint::GENERATOR
.to_encoded_point(false)
.x()
.unwrap(),
);
y.copy_from_slice(
p192::AffinePoint::GENERATOR
.to_encoded_point(false)
.y()
.unwrap(),
);
&EllipticCurve::P192
}
32 => {
x.copy_from_slice(
p256::AffinePoint::GENERATOR
.to_encoded_point(false)
.x()
.unwrap(),
);
y.copy_from_slice(
p256::AffinePoint::GENERATOR
.to_encoded_point(false)
.y()
.unwrap(),
);
&EllipticCurve::P256
}
_ => unimplemented!(),
};
let begin_time = SystemTimer::now();
ecc.affine_point_multiplication(curve, k, x, y)
.expect("Inputs data doesn't match the key length selected.");
let end_time = SystemTimer::now();
delta_time += end_time - begin_time;
let t2 = &mut [0_u8; 64];
let (sw_x, sw_y) = t2.split_at_mut(prime_field.len());
let (sw_y, _) = sw_y.split_at_mut(prime_field.len());
match prime_field.len() {
24 => {
let sw_k =
p192::Scalar::from(elliptic_curve::ScalarPrimitive::from_slice(k).unwrap());
let q = p192::AffinePoint::GENERATOR
.mul(sw_k)
.to_affine()
.to_encoded_point(false);
sw_x.copy_from_slice(q.x().unwrap().as_slice());
sw_y.copy_from_slice(q.y().unwrap().as_slice());
}
32 => {
let sw_k =
p256::Scalar::from(elliptic_curve::ScalarPrimitive::from_slice(k).unwrap());
let q = p256::AffinePoint::GENERATOR
.mul(sw_k)
.to_affine()
.to_encoded_point(false);
sw_x.copy_from_slice(q.x().unwrap().as_slice());
sw_y.copy_from_slice(q.y().unwrap().as_slice());
}
_ => unimplemented!(),
};
for (a, b) in x.iter().zip(sw_x) {
assert_eq!(
a, b,
"ECC failed during affine point multiplication with d_a = {:02X?} ({:02X?} != {:02X?})",
k, a, b,
);
}
for (a, b) in y.iter().zip(sw_y) {
assert_eq!(
a, b,
"ECC failed during affine point multiplication with d_a = {:02X?} ({:02X?} != {:02X?})",
k, a, b,
);
}
}
println!(
"ok (it took {} cycles in average)",
delta_time / (TEST_PARAMS_VECTOR.nb_loop_mul as u64)
);
}
}
fn test_finite_field_division(ecc: &mut Ecc, rng: &mut Rng) {
for &prime_field in TEST_PARAMS_VECTOR.prime_fields {
print!("Beginning finite field division tests over ");
match prime_field.len() {
24 => print!("P-192..."),
32 => print!("P-256..."),
_ => unimplemented!(),
};
let t1 = &mut [0_u8; 64];
let (k, y) = t1.split_at_mut(prime_field.len());
let (y, _) = y.split_at_mut(prime_field.len());
let mut delta_time = 0;
for _ in 0..TEST_PARAMS_VECTOR.nb_loop_inv {
loop {
rng.read(k).unwrap();
rng.read(y).unwrap();
let is_zero = k.iter().all(|&elt| elt == 0) || y.iter().all(|&elt| elt == 0);
let is_modulus = k.iter().zip(prime_field).all(|(&a, &b)| a == b)
|| y.iter().zip(prime_field).all(|(&a, &b)| a == b);
if is_zero == false && is_modulus == false {
break;
}
}
let t2 = &mut [0_u8; 96];
let (sw_y, sw_k) = t2.split_at_mut(prime_field.len());
let (sw_k, sw_res) = sw_k.split_at_mut(prime_field.len());
let (sw_res, _) = sw_res.split_at_mut(prime_field.len());
sw_y.copy_from_slice(y);
sw_k.copy_from_slice(k);
let curve = match prime_field.len() {
24 => &EllipticCurve::P192,
32 => &EllipticCurve::P256,
_ => unimplemented!(),
};
let begin_time = SystemTimer::now();
ecc.finite_field_division(curve, k, y)
.expect("Inputs data doesn't match the key length selected.");
let end_time = SystemTimer::now();
delta_time += end_time - begin_time;
match prime_field.len() {
24 => {
let modulus = DynResidueParams::new(&U192::from_be_slice(prime_field));
let sw_y = DynResidue::new(&U192::from_be_slice(sw_y), modulus);
let sw_k = DynResidue::new(&U192::from_be_slice(sw_k), modulus);
let sw_inv_k = sw_k.invert().0;
sw_res.copy_from_slice(sw_y.mul(&sw_inv_k).retrieve().to_be_bytes().as_slice());
}
32 => {
let modulus = DynResidueParams::new(&U256::from_be_slice(prime_field));
let sw_y = DynResidue::new(&U256::from_be_slice(sw_y), modulus);
let sw_k = DynResidue::new(&U256::from_be_slice(sw_k), modulus);
let sw_inv_k = sw_k.invert().0;
sw_res.copy_from_slice(sw_y.mul(&sw_inv_k).retrieve().to_be_bytes().as_slice());
}
_ => unimplemented!(),
};
for (a, b) in y.iter().zip(sw_res) {
assert_eq!(
a, b,
"ECC failed during finite field division with \np_y = {:02X?}\nk= {:02X?}",
sw_y, sw_k,
);
}
}
println!(
"ok (it took {} cycles in average)",
delta_time / (TEST_PARAMS_VECTOR.nb_loop_inv as u64)
);
}
}
fn test_affine_point_verification(ecc: &mut Ecc, rng: &mut Rng) {
for &prime_field in TEST_PARAMS_VECTOR.prime_fields {
print!("Beginning affine point verification tests over ");
match prime_field.len() {
24 => print!("secp192r1..."),
_ => print!("secp256r1..."),
};
let t1 = &mut [0_u8; 96];
let (k, x) = t1.split_at_mut(prime_field.len());
let (x, y) = x.split_at_mut(prime_field.len());
let (y, _) = y.split_at_mut(prime_field.len());
let mut delta_time = 0;
for _ in 0..TEST_PARAMS_VECTOR.nb_loop_mul {
loop {
rng.read(k).unwrap();
let is_zero = k.iter().all(|&elt| elt == 0);
let is_modulus = k.iter().zip(prime_field).all(|(&a, &b)| a == b);
if is_zero == false && is_modulus == false {
break;
}
}
let curve = match prime_field.len() {
24 => {
let sw_k =
p192::Scalar::from(elliptic_curve::ScalarPrimitive::from_slice(k).unwrap());
let q = p192::AffinePoint::GENERATOR
.mul(sw_k)
.to_affine()
.to_encoded_point(false);
x.copy_from_slice(q.x().unwrap().as_slice());
y.copy_from_slice(q.y().unwrap().as_slice());
&EllipticCurve::P192
}
32 => {
let sw_k =
p256::Scalar::from(elliptic_curve::ScalarPrimitive::from_slice(k).unwrap());
let q = p256::AffinePoint::GENERATOR
.mul(sw_k)
.to_affine()
.to_encoded_point(false);
x.copy_from_slice(q.x().unwrap().as_slice());
y.copy_from_slice(q.y().unwrap().as_slice());
&EllipticCurve::P256
}
_ => unimplemented!(),
};
let begin_time = SystemTimer::now();
match ecc.affine_point_verification(&curve, x, y) {
Err(Error::SizeMismatchCurve) => {
assert!(false, "Inputs data doesn't match the key length selected.")
}
Err(Error::PointNotOnSelectedCurve) => assert!(
false,
"ECC failed while affine point verification with x = {:02X?} and y = {:02X?}.",
x, y,
),
_ => {}
}
let end_time = SystemTimer::now();
delta_time += end_time - begin_time;
}
println!(
"ok (it took {} cycles in average)",
delta_time / (TEST_PARAMS_VECTOR.nb_loop_mul as u64)
);
}
}
fn test_afine_point_verification_multiplication(ecc: &mut Ecc, rng: &mut Rng) {
for &prime_field in TEST_PARAMS_VECTOR.prime_fields {
print!("Beginning affine point verification + multiplication tests over ");
match prime_field.len() {
24 => print!("secp192r1..."),
_ => print!("secp256r1..."),
};
let t1 = &mut [0_u8; 96];
let (k, x) = t1.split_at_mut(prime_field.len());
let (x, y) = x.split_at_mut(prime_field.len());
let (y, _) = y.split_at_mut(prime_field.len());
let mut delta_time = 0;
for _ in 0..TEST_PARAMS_VECTOR.nb_loop_mul {
loop {
rng.read(k).unwrap();
let is_zero = k.iter().all(|&elt| elt == 0);
let is_modulus = k.iter().zip(prime_field).all(|(&a, &b)| a == b);
if is_zero == false && is_modulus == false {
break;
}
}
let curve = match prime_field.len() {
24 => {
x.copy_from_slice(
p192::AffinePoint::GENERATOR
.to_encoded_point(false)
.x()
.unwrap(),
);
y.copy_from_slice(
p192::AffinePoint::GENERATOR
.to_encoded_point(false)
.y()
.unwrap(),
);
&EllipticCurve::P192
}
32 => {
x.copy_from_slice(
p256::AffinePoint::GENERATOR
.to_encoded_point(false)
.x()
.unwrap(),
);
y.copy_from_slice(
p256::AffinePoint::GENERATOR
.to_encoded_point(false)
.y()
.unwrap(),
);
&EllipticCurve::P256
}
_ => unimplemented!(),
};
let begin_time = SystemTimer::now();
match ecc.affine_point_verification_multiplication(curve, k, x, y) {
Err(Error::SizeMismatchCurve) => assert!(false, "Inputs data doesn't match the key length selected."),
Err(Error::PointNotOnSelectedCurve) => assert!(
false, "ECC failed while affine point verification + multiplication with x = {:02X?} and y = {:02X?}.",
x, y,
),
_ => {},
}
let end_time = SystemTimer::now();
delta_time += end_time - begin_time;
let t2 = &mut [0_u8; 64];
let (sw_x, sw_y) = t2.split_at_mut(prime_field.len());
let (sw_y, _) = sw_y.split_at_mut(prime_field.len());
match prime_field.len() {
24 => {
let sw_k =
p192::Scalar::from(elliptic_curve::ScalarPrimitive::from_slice(k).unwrap());
let q = p192::AffinePoint::GENERATOR
.mul(sw_k)
.to_affine()
.to_encoded_point(false);
sw_x.copy_from_slice(q.x().unwrap().as_slice());
sw_y.copy_from_slice(q.y().unwrap().as_slice());
}
32 => {
let sw_k =
p256::Scalar::from(elliptic_curve::ScalarPrimitive::from_slice(k).unwrap());
let q = p256::AffinePoint::GENERATOR
.mul(sw_k)
.to_affine()
.to_encoded_point(false);
sw_x.copy_from_slice(q.x().unwrap().as_slice());
sw_y.copy_from_slice(q.y().unwrap().as_slice());
}
_ => unimplemented!(),
};
for (a, b) in x.iter().zip(sw_x) {
assert_eq!(
a, b,
"ECC failed during affine point verification + multiplication with d_a = {:02X?} ({:02X?} != {:02X?})",
k, a, b,
);
}
for (a, b) in y.iter().zip(sw_y) {
assert_eq!(
a, b,
"ECC failed during affine point verification + multiplication with d_a = {:02X?} ({:02X?} != {:02X?})",
k, a, b,
);
}
}
println!(
"ok (it took {} cycles in average)",
delta_time / (TEST_PARAMS_VECTOR.nb_loop_mul as u64)
);
}
}
fn test_jacobian_point_multiplication(ecc: &mut Ecc, rng: &mut Rng) {
for &prime_field in TEST_PARAMS_VECTOR.prime_fields {
print!("Beginning jacobian point multiplication tests over ");
match prime_field.len() {
24 => print!("secp192r1..."),
_ => print!("secp256r1..."),
};
let t1 = &mut [0_u8; 96];
let (k, x) = t1.split_at_mut(prime_field.len());
let (x, y) = x.split_at_mut(prime_field.len());
let (y, _) = y.split_at_mut(prime_field.len());
let mut delta_time = 0;
for _ in 0..TEST_PARAMS_VECTOR.nb_loop_mul {
let t2 = &mut [0_u8; 96];
let (sw_x, sw_y) = t2.split_at_mut(prime_field.len());
let (sw_y, sw_k) = sw_y.split_at_mut(prime_field.len());
let (sw_k, _) = sw_k.split_at_mut(prime_field.len());
loop {
rng.read(k).unwrap();
let is_zero = k.iter().all(|&elt| elt == 0);
let is_modulus = k.iter().zip(prime_field).all(|(&a, &b)| a == b);
if is_zero == false && is_modulus == false {
break;
}
}
sw_k.copy_from_slice(k);
let curve = match prime_field.len() {
24 => {
x.copy_from_slice(
p192::AffinePoint::GENERATOR
.to_encoded_point(false)
.x()
.unwrap(),
);
y.copy_from_slice(
p192::AffinePoint::GENERATOR
.to_encoded_point(false)
.y()
.unwrap(),
);
&EllipticCurve::P192
}
32 => {
x.copy_from_slice(
p256::AffinePoint::GENERATOR
.to_encoded_point(false)
.x()
.unwrap(),
);
y.copy_from_slice(
p256::AffinePoint::GENERATOR
.to_encoded_point(false)
.y()
.unwrap(),
);
&EllipticCurve::P256
}
_ => unimplemented!(),
};
let begin_time = SystemTimer::now();
ecc.jacobian_point_multiplication(curve, k, x, y)
.expect("Inputs data doesn't match the key length selected.");
let end_time = SystemTimer::now();
delta_time += end_time - begin_time;
match prime_field.len() {
24 => {
let sw_k = p192::Scalar::from(
elliptic_curve::ScalarPrimitive::from_slice(sw_k).unwrap(),
);
let q = p192::AffinePoint::GENERATOR
.mul(sw_k)
.to_affine()
.to_encoded_point(false);
let modulus = DynResidueParams::new(&U192::from_be_slice(prime_field));
let x_affine =
DynResidue::new(&U192::from_be_slice(q.x().unwrap().as_slice()), modulus);
let y_affine =
DynResidue::new(&U192::from_be_slice(q.y().unwrap().as_slice()), modulus);
let z = DynResidue::new(&U192::from_be_slice(k), modulus);
let x_jacobian = x_affine * z * z;
let y_jacobian = y_affine * z * z * z;
sw_x.copy_from_slice(x_jacobian.retrieve().to_be_bytes().as_slice());
sw_y.copy_from_slice(y_jacobian.retrieve().to_be_bytes().as_slice());
}
32 => {
let sw_k = p256::Scalar::from(
elliptic_curve::ScalarPrimitive::from_slice(sw_k).unwrap(),
);
let q = p256::AffinePoint::GENERATOR
.mul(sw_k)
.to_affine()
.to_encoded_point(false);
let modulus = DynResidueParams::new(&U256::from_be_slice(prime_field));
let x_affine =
DynResidue::new(&U256::from_be_slice(q.x().unwrap().as_slice()), modulus);
let y_affine =
DynResidue::new(&U256::from_be_slice(q.y().unwrap().as_slice()), modulus);
let z = DynResidue::new(&U256::from_be_slice(k), modulus);
let x_jacobian = x_affine * z * z;
let y_jacobian = y_affine * z * z * z;
sw_x.copy_from_slice(x_jacobian.retrieve().to_be_bytes().as_slice());
sw_y.copy_from_slice(y_jacobian.retrieve().to_be_bytes().as_slice());
}
_ => unimplemented!(),
};
for (a, b) in x.iter().zip(sw_x.iter()) {
assert_eq!(
a, b,
"ECC failed during jacobian point multiplication.\nX = {:02X?}\nX = {:02X?}",
x, sw_x,
);
}
for (a, b) in y.iter().zip(sw_y.iter()) {
assert_eq!(
a, b,
"ECC failed during jacobian point multiplication.\nY = {:02X?}\nY = {:02X?}",
y, sw_y,
);
}
}
println!(
"ok (it took {} cycles in average)",
delta_time / (TEST_PARAMS_VECTOR.nb_loop_mul as u64)
);
}
}
fn test_jacobian_point_verification(ecc: &mut Ecc, rng: &mut Rng) {
for &prime_field in TEST_PARAMS_VECTOR.prime_fields {
print!("Beginning jacobian point verification tests over ");
match prime_field.len() {
24 => print!("secp192r1..."),
_ => print!("secp256r1..."),
};
let t1 = &mut [0_u8; 128];
let (k, x) = t1.split_at_mut(prime_field.len());
let (x, y) = x.split_at_mut(prime_field.len());
let (y, z) = y.split_at_mut(prime_field.len());
let (z, _) = z.split_at_mut(prime_field.len());
let mut delta_time = 0;
for _ in 0..TEST_PARAMS_VECTOR.nb_loop_mul {
loop {
rng.read(k).unwrap();
rng.read(z).unwrap();
let is_zero = k.iter().all(|&elt| elt == 0) || z.iter().all(|&elt| elt == 0);
let is_modulus = k.iter().zip(prime_field).all(|(&a, &b)| a == b)
|| z.iter().zip(prime_field).all(|(&a, &b)| a == b);
if is_zero == false && is_modulus == false {
break;
}
}
let curve = match prime_field.len() {
24 => {
let sw_k =
p192::Scalar::from(elliptic_curve::ScalarPrimitive::from_slice(k).unwrap());
let q = p192::AffinePoint::GENERATOR
.mul(sw_k)
.to_affine()
.to_encoded_point(false);
let modulus = DynResidueParams::new(&U192::from_be_slice(prime_field));
let x_affine =
DynResidue::new(&U192::from_be_slice(q.x().unwrap().as_slice()), modulus);
let y_affine =
DynResidue::new(&U192::from_be_slice(q.y().unwrap().as_slice()), modulus);
let z = DynResidue::new(&U192::from_be_slice(z), modulus);
let x_jacobian = x_affine * z * z;
let y_jacobian = y_affine * z * z * z;
x.copy_from_slice(x_jacobian.retrieve().to_be_bytes().as_slice());
y.copy_from_slice(y_jacobian.retrieve().to_be_bytes().as_slice());
&EllipticCurve::P192
}
32 => {
let sw_k =
p256::Scalar::from(elliptic_curve::ScalarPrimitive::from_slice(k).unwrap());
let q = p256::AffinePoint::GENERATOR
.mul(sw_k)
.to_affine()
.to_encoded_point(false);
let modulus = DynResidueParams::new(&U256::from_be_slice(prime_field));
let x_affine =
DynResidue::new(&U256::from_be_slice(q.x().unwrap().as_slice()), modulus);
let y_affine =
DynResidue::new(&U256::from_be_slice(q.y().unwrap().as_slice()), modulus);
let z = DynResidue::new(&U256::from_be_slice(z), modulus);
let x_jacobian = x_affine * z * z;
let y_jacobian = y_affine * z * z * z;
x.copy_from_slice(x_jacobian.retrieve().to_be_bytes().as_slice());
y.copy_from_slice(y_jacobian.retrieve().to_be_bytes().as_slice());
&EllipticCurve::P256
}
_ => unimplemented!(),
};
let begin_time = SystemTimer::now();
match ecc.jacobian_point_verification(&curve, x, y, z) {
Err(Error::SizeMismatchCurve) => {
assert!(false, "Inputs data doesn't match the key length selected.")
}
Err(Error::PointNotOnSelectedCurve) => assert!(
false,
"ECC failed while base point verification with x = {:02X?} and y = {:02X?}.",
x, y,
),
_ => {}
}
let end_time = SystemTimer::now();
delta_time += end_time - begin_time;
}
println!(
"ok (it took {} cycles in average)",
delta_time / (TEST_PARAMS_VECTOR.nb_loop_mul as u64)
);
}
}
fn test_afine_point_verification_jacobian_multiplication(ecc: &mut Ecc, rng: &mut Rng) {
for &prime_field in TEST_PARAMS_VECTOR.prime_fields {
print!("Beginning affine point verification + jacobian point multiplication tests over ");
match prime_field.len() {
24 => print!("secp192r1..."),
_ => print!("secp256r1..."),
};
let t1 = &mut [0_u8; 96];
let (k, x) = t1.split_at_mut(prime_field.len());
let (x, y) = x.split_at_mut(prime_field.len());
let (y, _) = y.split_at_mut(prime_field.len());
let mut delta_time = 0;
for _ in 0..TEST_PARAMS_VECTOR.nb_loop_mul {
let t2 = &mut [0_u8; 96];
let (sw_x, sw_y) = t2.split_at_mut(prime_field.len());
let (sw_y, sw_k) = sw_y.split_at_mut(prime_field.len());
let (sw_k, _) = sw_k.split_at_mut(prime_field.len());
loop {
rng.read(k).unwrap();
let is_zero = k.iter().all(|&elt| elt == 0);
let is_modulus = k.iter().zip(prime_field).all(|(&a, &b)| a == b);
if is_zero == false && is_modulus == false {
break;
}
}
sw_k.copy_from_slice(k);
let curve = match prime_field.len() {
24 => {
x.copy_from_slice(
p192::AffinePoint::GENERATOR
.to_encoded_point(false)
.x()
.unwrap(),
);
y.copy_from_slice(
p192::AffinePoint::GENERATOR
.to_encoded_point(false)
.y()
.unwrap(),
);
&EllipticCurve::P192
}
32 => {
x.copy_from_slice(
p256::AffinePoint::GENERATOR
.to_encoded_point(false)
.x()
.unwrap(),
);
y.copy_from_slice(
p256::AffinePoint::GENERATOR
.to_encoded_point(false)
.y()
.unwrap(),
);
&EllipticCurve::P256
}
_ => unimplemented!(),
};
let begin_time = SystemTimer::now();
match ecc.affine_point_verification_jacobian_multiplication(curve, k, x, y) {
Err(Error::SizeMismatchCurve) => assert!(false, "Inputs data doesn't match the key length selected."),
Err(Error::PointNotOnSelectedCurve) => assert!(
false, "ECC failed while affine point verification + multiplication with x = {:02X?} and y = {:02X?}.",
x, y,
),
_ => {},
}
let end_time = SystemTimer::now();
delta_time += end_time - begin_time;
match prime_field.len() {
24 => {
let sw_k = p192::Scalar::from(
elliptic_curve::ScalarPrimitive::from_slice(sw_k).unwrap(),
);
let q = p192::AffinePoint::GENERATOR
.mul(sw_k)
.to_affine()
.to_encoded_point(false);
let modulus = DynResidueParams::new(&U192::from_be_slice(prime_field));
let x_affine =
DynResidue::new(&U192::from_be_slice(q.x().unwrap().as_slice()), modulus);
let y_affine =
DynResidue::new(&U192::from_be_slice(q.y().unwrap().as_slice()), modulus);
let z = DynResidue::new(&U192::from_be_slice(k), modulus);
let x_jacobian = x_affine * z * z;
let y_jacobian = y_affine * z * z * z;
sw_x.copy_from_slice(x_jacobian.retrieve().to_be_bytes().as_slice());
sw_y.copy_from_slice(y_jacobian.retrieve().to_be_bytes().as_slice());
}
32 => {
let sw_k = p256::Scalar::from(
elliptic_curve::ScalarPrimitive::from_slice(sw_k).unwrap(),
);
let q = p256::AffinePoint::GENERATOR
.mul(sw_k)
.to_affine()
.to_encoded_point(false);
let modulus = DynResidueParams::new(&U256::from_be_slice(prime_field));
let x_affine =
DynResidue::new(&U256::from_be_slice(q.x().unwrap().as_slice()), modulus);
let y_affine =
DynResidue::new(&U256::from_be_slice(q.y().unwrap().as_slice()), modulus);
let z = DynResidue::new(&U256::from_be_slice(k), modulus);
let x_jacobian = x_affine * z * z;
let y_jacobian = y_affine * z * z * z;
sw_x.copy_from_slice(x_jacobian.retrieve().to_be_bytes().as_slice());
sw_y.copy_from_slice(y_jacobian.retrieve().to_be_bytes().as_slice());
}
_ => unimplemented!(),
};
for (a, b) in x.iter().zip(sw_x.iter()) {
assert_eq!(
a, b,
"ECC failed during affine point verification + jacobian point multiplication.\nX = {:02X?}\nX = {:02X?}",
x, sw_x,
);
}
for (a, b) in y.iter().zip(sw_y.iter()) {
assert_eq!(
a, b,
"ECC failed during affine point verification + jacobian point multiplication.\nY = {:02X?}\nY = {:02X?}",
y, sw_y,
);
}
}
println!(
"ok (it took {} cycles in average)",
delta_time / (TEST_PARAMS_VECTOR.nb_loop_mul as u64)
);
}
}