use arithmetic::montgomery::*;
use error;
use super::ops::*;
use super::verify_affine_point_is_on_the_curve;
use untrusted;
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 test;
use super::*;
use super::super::ops;
use untrusted;
#[test]
fn parse_uncompressed_point_test() {
test::from_file("src/ec/suite_b/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 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!(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);
}
}
}