* Unify the system peripheral Whilst the PCR, SYSTEM and DPORT peripherals are different, we currently use them all in the same way. This PR unifies the peripheral name in the hal to `SYSTEM`. The idea is that they all do the same sort of thing, so we can collect them under the same name, and later down the line we can being to expose differences under an extended API. The benifits to this are imo quite big, the examples now are all identical, which makes things easier for esp-wifi, and paves a path towards the multichip hal. Why not do this in the PAC? Imo the pac should be as close to the hardware as possible, and the HAL is where we should abstractions such as this. * changelog
725 lines
29 KiB
Rust
725 lines
29 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 esp32c6_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,
|
|
}
|
|
|
|
const TEST_PARAMS_VECTOR: TestParams = TestParams {
|
|
prime_fields: &[
|
|
&hex!("fffffffffffffffffffffffffffffffeffffffffffffffff"),
|
|
&hex!("ffffffff00000001000000000000000000000000ffffffffffffffffffffffff"),
|
|
],
|
|
nb_loop_mul: 10,
|
|
};
|
|
|
|
#[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_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_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)
|
|
);
|
|
}
|
|
}
|