Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ec/suite_b: Consistently use let {q,n} = & for moduli. #2180

Merged
merged 1 commit into from
Dec 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions src/ec/suite_b/ecdh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ fn ecdh(
// The "NSA Guide" steps are from section 3.1 of the NSA guide, "Ephemeral
// Unified Model."

let q = public_key_ops.common.elem_modulus();
let q = &public_key_ops.common.elem_modulus();

// NSA Guide Step 1 is handled separately.

Expand All @@ -103,7 +103,7 @@ fn ecdh(
// `parse_uncompressed_point` verifies that the point is not at infinity
// and that it is on the curve, using the Partial Public-Key Validation
// Routine.
let peer_public_key = parse_uncompressed_point(public_key_ops, &q, peer_public_key, cpu)?;
let peer_public_key = parse_uncompressed_point(public_key_ops, q, peer_public_key, cpu)?;

// NIST SP 800-56Ar2 Step 1.
// NSA Guide Step 3 (except point at infinity check).
Expand All @@ -125,8 +125,8 @@ fn ecdh(
// information about their values can be recovered. This doesn't meet the
// NSA guide's explicit requirement to "zeroize" them though.
// TODO: this only needs common scalar ops
let n = private_key_ops.common.scalar_modulus();
let my_private_key = private_key_as_scalar(&n, my_private_key);
let n = &private_key_ops.common.scalar_modulus();
let my_private_key = private_key_as_scalar(n, my_private_key);
let product = private_key_ops.point_mul(&my_private_key, &peer_public_key, cpu);

// NIST SP 800-56Ar2 Steps 2, 3, 4, and 5.
Expand All @@ -137,7 +137,7 @@ fn ecdh(
// `big_endian_affine_from_jacobian` verifies that the result is not at
// infinity and also does an extra check to verify that the point is on
// the curve.
big_endian_affine_from_jacobian(private_key_ops, &q, out, None, &product, cpu)
big_endian_affine_from_jacobian(private_key_ops, q, out, None, &product, cpu)

// NSA Guide Step 5 & 6 are deferred to the caller. Again, we have a
// pretty liberal interpretation of the NIST's spec's "Destroy" that
Expand Down
6 changes: 3 additions & 3 deletions src/ec/suite_b/ecdsa/digest_scalar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,20 +91,20 @@ mod tests {
panic!("Unsupported curve+digest: {}+{}", curve_name, digest_name);
}
};
let n = ops.scalar_ops.scalar_modulus();
let n = &ops.scalar_ops.scalar_modulus();

assert_eq!(input.len(), digest_alg.output_len());
assert_eq!(output.len(), ops.scalar_ops.scalar_bytes_len());
assert_eq!(output.len(), n.bytes_len());

let expected = scalar_parse_big_endian_variable(
&n,
n,
limb::AllowZero::Yes,
untrusted::Input::from(&output),
)
.unwrap();

let actual = digest_bytes_scalar(&n, &input);
let actual = digest_bytes_scalar(n, &input);
assert_eq!(
ops.scalar_ops.leak_limbs(&actual),
ops.scalar_ops.leak_limbs(&expected)
Expand Down
14 changes: 7 additions & 7 deletions src/ec/suite_b/ecdsa/signing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,8 +156,8 @@ impl EcdsaKeyPair {
let cpu = cpu::features();

let (seed, public_key) = key_pair.split();
let n = alg.private_scalar_ops.scalar_ops.scalar_modulus();
let d = private_key::private_key_as_scalar(&n, &seed);
let n = &alg.private_scalar_ops.scalar_ops.scalar_modulus();
let d = private_key::private_key_as_scalar(n, &seed);
let d = alg.private_scalar_ops.to_mont(&d, cpu);

let nonce_key = NonceRandomKey::new(alg, &seed, rng)?;
Expand Down Expand Up @@ -240,21 +240,21 @@ impl EcdsaKeyPair {
let scalar_ops = ops.scalar_ops;
let cops = scalar_ops.common;
let private_key_ops = self.alg.private_key_ops;
let q = cops.elem_modulus();
let n = scalar_ops.scalar_modulus();
let q = &cops.elem_modulus();
let n = &scalar_ops.scalar_modulus();

for _ in 0..100 {
// XXX: iteration conut?
// Step 1.
let k = private_key::random_scalar(self.alg.private_key_ops, &n, rng)?;
let k = private_key::random_scalar(self.alg.private_key_ops, n, rng)?;
let k_inv = ops.scalar_inv_to_mont(&k, cpu);

// Step 2.
let r = private_key_ops.point_mul_base(&k, cpu);

// Step 3.
let r = {
let (x, _) = private_key::affine_from_jacobian(private_key_ops, &q, &r, cpu)?;
let (x, _) = private_key::affine_from_jacobian(private_key_ops, q, &r, cpu)?;
let x = cops.elem_unencoded(&x);
n.elem_reduced_to_scalar(&x)
};
Expand All @@ -265,7 +265,7 @@ impl EcdsaKeyPair {
// Step 4 is done by the caller.

// Step 5.
let e = digest_scalar(&n, h);
let e = digest_scalar(n, h);

// Step 6.
let s = {
Expand Down
20 changes: 10 additions & 10 deletions src/ec/suite_b/ecdsa/verification.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ impl signature::VerificationAlgorithm for EcdsaVerificationAlgorithm {

// NSA Guide Step 3: "Convert the bit string H to an integer e as
// described in Appendix B.2."
let n = self.ops.scalar_ops.scalar_modulus();
digest_scalar(&n, h)
let n = &self.ops.scalar_ops.scalar_modulus();
digest_scalar(n, h)
};

self.verify_digest(public_key, e, signature)
Expand All @@ -85,8 +85,8 @@ impl EcdsaVerificationAlgorithm {

let public_key_ops = self.ops.public_key_ops;
let scalar_ops = self.ops.scalar_ops;
let q = public_key_ops.common.elem_modulus();
let n = scalar_ops.scalar_modulus();
let q = &public_key_ops.common.elem_modulus();
let n = &scalar_ops.scalar_modulus();

// NSA Guide Prerequisites:
//
Expand All @@ -105,16 +105,16 @@ impl EcdsaVerificationAlgorithm {
// can do. Prerequisite #2 is handled implicitly as the domain
// parameters are hard-coded into the source. Prerequisite #3 is
// handled by `parse_uncompressed_point`.
let peer_pub_key = parse_uncompressed_point(public_key_ops, &q, public_key, cpu)?;
let peer_pub_key = parse_uncompressed_point(public_key_ops, q, public_key, cpu)?;

let (r, s) = signature.read_all(error::Unspecified, |input| {
(self.split_rs)(scalar_ops, input)
})?;

// NSA Guide Step 1: "If r and s are not both integers in the interval
// [1, n − 1], output INVALID."
let r = scalar_parse_big_endian_variable(&n, limb::AllowZero::No, r)?;
let s = scalar_parse_big_endian_variable(&n, limb::AllowZero::No, s)?;
let r = scalar_parse_big_endian_variable(n, limb::AllowZero::No, r)?;
let s = scalar_parse_big_endian_variable(n, limb::AllowZero::No, s)?;

// NSA Guide Step 4: "Compute w = s**−1 mod n, using the routine in
// Appendix B.1."
Expand All @@ -137,7 +137,7 @@ impl EcdsaVerificationAlgorithm {
// `verify_affine_point_is_on_the_curve_scaled` for details on why).
// But, we're going to avoid converting to affine for performance
// reasons, so we do the verification using the Jacobian coordinates.
let z2 = verify_jacobian_point_is_on_the_curve(public_key_ops.common, &q, &product)?;
let z2 = verify_jacobian_point_is_on_the_curve(public_key_ops.common, q, &product)?;

// NSA Guide Step 7: "Compute v = xR mod n."
// NSA Guide Step 8: "Compare v and r0. If v = r0, output VALID;
Expand Down Expand Up @@ -319,9 +319,9 @@ mod tests {
panic!("Unsupported curve: {}", curve_name);
}
};
let n = alg.ops.scalar_ops.scalar_modulus();
let n = &alg.ops.scalar_ops.scalar_modulus();

let digest = super::super::digest_scalar::digest_bytes_scalar(&n, &digest[..]);
let digest = super::super::digest_scalar::digest_bytes_scalar(n, &digest[..]);
let actual_result = alg.verify_digest(
untrusted::Input::from(&public_key[..]),
digest,
Expand Down
30 changes: 15 additions & 15 deletions src/ec/suite_b/ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -557,7 +557,7 @@ mod tests {

fn q_minus_n_plus_n_equals_0_test(ops: &PublicScalarOps) {
let cops = ops.scalar_ops.common;
let q = cops.elem_modulus();
let q = &cops.elem_modulus();
let mut x = Elem::from(&ops.q_minus_n);
q.elem_add(&mut x, &Elem::from(&cops.n));
assert!(cops.is_zero(&x));
Expand Down Expand Up @@ -804,12 +804,12 @@ mod tests {
fn scalar_mul_test(ops: &ScalarOps, test_file: test::File) {
let cpu = cpu::features();
let cops = ops.common;
let n = cops.scalar_modulus();
let n = &cops.scalar_modulus();
test::run(test_file, |section, test_case| {
assert_eq!(section, "");
let a = consume_scalar(&n, test_case, "a");
let b = consume_scalar_mont(&n, test_case, "b");
let expected_result = consume_scalar(&n, test_case, "r");
let a = consume_scalar(n, test_case, "a");
let b = consume_scalar_mont(n, test_case, "b");
let expected_result = consume_scalar(n, test_case, "r");
let actual_result = ops.scalar_product(&a, &b, cpu);
assert_limbs_are_equal(cops, &actual_result.limbs, &expected_result.limbs);

Expand Down Expand Up @@ -838,12 +838,12 @@ mod tests {
test_file: test::File,
) {
let cops = ops.common;
let n = cops.scalar_modulus();
let n = &cops.scalar_modulus();
test::run(test_file, |section, test_case| {
assert_eq!(section, "");
let cpu = cpu::features();
let a = consume_scalar(&n, test_case, "a");
let expected_result = consume_scalar(&n, test_case, "r");
let a = consume_scalar(n, test_case, "a");
let expected_result = consume_scalar(n, test_case, "r");

{
let mut actual_result: Scalar<R> = Scalar {
Expand Down Expand Up @@ -1056,16 +1056,16 @@ mod tests {
) {
let cpu = cpu::features();
let cops = pub_ops.common;
let q = cops.elem_modulus();
let n = cops.scalar_modulus();
let q = &cops.elem_modulus();
let n = &cops.scalar_modulus();
test::run(test_file, |section, test_case| {
assert_eq!(section, "");
let p_scalar = consume_scalar(&n, test_case, "p_scalar");
let p_scalar = consume_scalar(n, test_case, "p_scalar");

let p = test_case.consume_bytes("p");
let p = super::super::public_key::parse_uncompressed_point(
pub_ops,
&q,
q,
untrusted::Input::from(&p),
cpu,
)
Expand All @@ -1080,7 +1080,7 @@ mod tests {
let (x, y) = actual_result[1..].split_at_mut(cops.len());
super::super::private_key::big_endian_affine_from_jacobian(
priv_ops,
&q,
q,
x,
Some(y),
&product,
Expand Down Expand Up @@ -1119,10 +1119,10 @@ mod tests {
test_file: test::File,
) {
let cpu = cpu::features();
let n = ops.common.scalar_modulus();
let n = &ops.common.scalar_modulus();
test::run(test_file, |section, test_case| {
assert_eq!(section, "");
let g_scalar = consume_scalar(&n, test_case, "g_scalar");
let g_scalar = consume_scalar(n, test_case, "g_scalar");
let expected_result: TestPoint<Unencoded> = consume_point(ops, test_case, "r");
let actual_result = f(&g_scalar, cpu);
assert_point_actual_equals_expected(ops, &actual_result, &expected_result);
Expand Down
12 changes: 6 additions & 6 deletions src/ec/suite_b/private_key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,8 @@ pub(super) fn check_scalar_big_endian_bytes(
bytes: &[u8],
) -> Result<(), error::Unspecified> {
debug_assert_eq!(bytes.len(), ops.common.len());
let n = ops.common.scalar_modulus();
scalar_from_big_endian_bytes(&n, bytes).map(|_| ())
let n = &ops.common.scalar_modulus();
scalar_from_big_endian_bytes(n, bytes).map(|_| ())
}

// Parses a fixed-length (zero-padded) big-endian-encoded scalar in the range
Expand Down Expand Up @@ -132,18 +132,18 @@ pub(super) fn public_from_private(
my_private_key: &ec::Seed,
cpu: cpu::Features,
) -> Result<(), error::Unspecified> {
let q = ops.common.elem_modulus();
let q = &ops.common.elem_modulus();
let elem_and_scalar_bytes = ops.common.len();
debug_assert_eq!(public_out.len(), 1 + (2 * elem_and_scalar_bytes));
let n = ops.common.scalar_modulus();
let my_private_key = private_key_as_scalar(&n, my_private_key);
let n = &ops.common.scalar_modulus();
let my_private_key = private_key_as_scalar(n, my_private_key);
let my_public_key = ops.point_mul_base(&my_private_key, cpu);
public_out[0] = 4; // Uncompressed encoding.
let (x_out, y_out) = public_out[1..].split_at_mut(elem_and_scalar_bytes);

// `big_endian_affine_from_jacobian` verifies that the point is not at
// infinity and is on the curve.
big_endian_affine_from_jacobian(ops, &q, x_out, Some(y_out), &my_public_key, cpu)
big_endian_affine_from_jacobian(ops, q, x_out, Some(y_out), &my_public_key, cpu)
}

pub(super) fn affine_from_jacobian(
Expand Down
4 changes: 2 additions & 2 deletions src/ec/suite_b/public_key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,9 @@ mod tests {
let is_valid = test_case.consume_string("Result") == "P";

let curve_ops = public_key_ops_from_curve_name(&curve_name);
let q = curve_ops.common.elem_modulus();
let q = &curve_ops.common.elem_modulus();

let result = parse_uncompressed_point(curve_ops, &q, public_key, cpu);
let result = parse_uncompressed_point(curve_ops, q, public_key, cpu);
assert_eq!(is_valid, result.is_ok());

// TODO: Verify that we when we re-serialize the parsed (x, y), the
Expand Down