use super::{ops::*, verify_affine_point_is_on_the_curve};
use crate::{arithmetic::montgomery::*, error};
pub fn parse_uncompressed_point(
ops: &PublicKeyOps,
input: untrusted::Input,
) -> Result<(Elem<R>, Elem<R>), error::Unspecified> {
let (x, y) = input.read_all(error::Unspecified, |input| {
let encoding = input.read_byte()?;
if encoding != 4 {
return Err(error::Unspecified);
}
let x = ops.elem_parse(input)?;
let y = ops.elem_parse(input)?;
Ok((x, y))
})?;
verify_affine_point_is_on_the_curve(ops.common, (&x, &y))?;
Ok((x, y))
}
#[cfg(test)]
mod tests {
use super::{super::ops, *};
use crate::test;
#[test]
fn parse_uncompressed_point_test() {
test::run(
test_file!("suite_b_public_key_tests.txt"),
|section, test_case| {
assert_eq!(section, "");
let curve_name = test_case.consume_string("Curve");
let public_key = test_case.consume_bytes("Q");
let public_key = untrusted::Input::from(&public_key);
let is_valid = test_case.consume_string("Result") == "P";
let curve_ops = public_key_ops_from_curve_name(&curve_name);
let result = parse_uncompressed_point(curve_ops, public_key);
assert_eq!(is_valid, result.is_ok());
Ok(())
},
);
}
fn public_key_ops_from_curve_name(curve_name: &str) -> &'static PublicKeyOps {
if curve_name == "P-256" {
&ops::p256::PUBLIC_KEY_OPS
} else if curve_name == "P-384" {
&ops::p384::PUBLIC_KEY_OPS
} else {
panic!("Unsupported curve: {}", curve_name);
}
}
}