From b41ecdb724a54ad51c886452d2497310da82cde2 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 21 Apr 2021 08:24:00 -0700 Subject: [PATCH] Add `Order` constants to all curve implementations (#328) Allows checking that a scalar field element is in range generically without a curve arithmetic implementation. --- Cargo.lock | 6 ++-- bp256/Cargo.toml | 2 +- bp256/src/r1.rs | 28 +++++++++++++++++++ bp256/src/t1.rs | 28 +++++++++++++++++++ bp384/Cargo.toml | 2 +- bp384/src/r1.rs | 34 +++++++++++++++++++++++ bp384/src/t1.rs | 34 +++++++++++++++++++++++ k256/Cargo.toml | 2 +- k256/src/arithmetic/scalar/scalar_4x64.rs | 10 ++----- k256/src/lib.rs | 28 +++++++++++++++++++ p256/Cargo.toml | 2 +- p256/src/lib.rs | 28 +++++++++++++++++++ p384/Cargo.toml | 2 +- p384/src/lib.rs | 34 +++++++++++++++++++++++ 14 files changed, 225 insertions(+), 15 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 54ab8bb2..16ddf7a3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -312,13 +312,13 @@ checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" [[package]] name = "elliptic-curve" -version = "0.9.6" +version = "0.9.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78fff5a5d53c2e45c2772aa2666904eaf5af581b9fc356b9da42b52bda088e6d" +checksum = "b9fdd441b650cf8d7c1d46836e2bb6df9c1d061faac35bacd02d2d6d7164455e" dependencies = [ "base64ct", + "bitvec", "ff", - "funty", "generic-array", "group", "hex-literal", diff --git a/bp256/Cargo.toml b/bp256/Cargo.toml index c56050e9..86881f40 100644 --- a/bp256/Cargo.toml +++ b/bp256/Cargo.toml @@ -13,7 +13,7 @@ keywords = ["brainpool", "crypto", "ecc"] [dependencies] ecdsa = { version = "=0.11.0-pre.4", optional = true, default-features = false, features = ["der"] } -elliptic-curve = { version = "0.9", default-features = false, features = ["hazmat"] } +elliptic-curve = { version = "0.9.7", default-features = false, features = ["hazmat"] } sha2 = { version = "0.9", optional = true, default-features = false } [features] diff --git a/bp256/src/r1.rs b/bp256/src/r1.rs index a276ab2d..3a75feb3 100644 --- a/bp256/src/r1.rs +++ b/bp256/src/r1.rs @@ -18,6 +18,34 @@ impl elliptic_curve::Curve for BrainpoolP256r1 { type FieldSize = U32; } +#[cfg(target_pointer_width = "32")] +impl elliptic_curve::Order for BrainpoolP256r1 { + type Limbs = [u32; 8]; + + const ORDER: [u32; 8] = [ + 0x9748_56a7, + 0x901e_0e82, + 0xb561_a6f7, + 0x8c39_7aa3, + 0x9d83_8d71, + 0x3e66_0a90, + 0xa1ee_a9bc, + 0xa9fb_57db, + ]; +} + +#[cfg(target_pointer_width = "64")] +impl elliptic_curve::Order for BrainpoolP256r1 { + type Limbs = [u64; 4]; + + const ORDER: Self::Limbs = [ + 0x901e_0e82_9748_56a7, + 0x8c39_7aa3_b561_a6f7, + 0x3e66_0a90_9d83_8d71, + 0xa9fb_57db_a1ee_a9bc, + ]; +} + impl elliptic_curve::weierstrass::Curve for BrainpoolP256r1 {} impl elliptic_curve::weierstrass::PointCompression for BrainpoolP256r1 { diff --git a/bp256/src/t1.rs b/bp256/src/t1.rs index 73407741..5230bd29 100644 --- a/bp256/src/t1.rs +++ b/bp256/src/t1.rs @@ -18,6 +18,34 @@ impl elliptic_curve::Curve for BrainpoolP256t1 { type FieldSize = U32; } +#[cfg(target_pointer_width = "32")] +impl elliptic_curve::Order for BrainpoolP256t1 { + type Limbs = [u32; 8]; + + const ORDER: [u32; 8] = [ + 0x9748_56a7, + 0x901e_0e82, + 0xb561_a6f7, + 0x8c39_7aa3, + 0x9d83_8d71, + 0x3e66_0a90, + 0xa1ee_a9bc, + 0xa9fb_57db, + ]; +} + +#[cfg(target_pointer_width = "64")] +impl elliptic_curve::Order for BrainpoolP256t1 { + type Limbs = [u64; 4]; + + const ORDER: Self::Limbs = [ + 0x901e_0e82_9748_56a7, + 0x8c39_7aa3_b561_a6f7, + 0x3e66_0a90_9d83_8d71, + 0xa9fb_57db_a1ee_a9bc, + ]; +} + impl elliptic_curve::weierstrass::Curve for BrainpoolP256t1 {} impl elliptic_curve::weierstrass::PointCompression for BrainpoolP256t1 { diff --git a/bp384/Cargo.toml b/bp384/Cargo.toml index 2de97ae1..21464684 100644 --- a/bp384/Cargo.toml +++ b/bp384/Cargo.toml @@ -13,7 +13,7 @@ keywords = ["brainpool", "crypto", "ecc"] [dependencies] ecdsa = { version = "=0.11.0-pre.4", optional = true, default-features = false, features = ["der"] } -elliptic-curve = { version = "0.9", default-features = false, features = ["hazmat"] } +elliptic-curve = { version = "0.9.7", default-features = false, features = ["hazmat"] } sha2 = { version = "0.9", optional = true, default-features = false } [features] diff --git a/bp384/src/r1.rs b/bp384/src/r1.rs index deab5707..8d302408 100644 --- a/bp384/src/r1.rs +++ b/bp384/src/r1.rs @@ -18,6 +18,40 @@ impl elliptic_curve::Curve for BrainpoolP384r1 { type FieldSize = U32; } +#[cfg(target_pointer_width = "32")] +impl elliptic_curve::Order for BrainpoolP384r1 { + type Limbs = [u32; 12]; + + const ORDER: Self::Limbs = [ + 0xe904_6565, + 0x3b88_3202, + 0x6b7f_c310, + 0xcf3a_b6af, + 0xac04_25a7, + 0x1f16_6e6c, + 0xed54_56b3, + 0x152f_7109, + 0x50e6_41df, + 0x0f5d_6f7e, + 0xa338_6d28, + 0x8cb9_1e82, + ]; +} + +#[cfg(target_pointer_width = "64")] +impl elliptic_curve::Order for BrainpoolP384r1 { + type Limbs = [u64; 6]; + + const ORDER: Self::Limbs = [ + 0x3b88_3202_e904_6565, + 0xcf3a_b6af_6b7f_c310, + 0x1f16_6e6c_ac04_25a7, + 0x152f_7109_ed54_56b3, + 0x0f5d_6f7e_50e6_41df, + 0x8cb9_1e82_a338_6d28, + ]; +} + impl elliptic_curve::weierstrass::Curve for BrainpoolP384r1 {} impl elliptic_curve::weierstrass::PointCompression for BrainpoolP384r1 { diff --git a/bp384/src/t1.rs b/bp384/src/t1.rs index 4ba5fc97..bb5d59a7 100644 --- a/bp384/src/t1.rs +++ b/bp384/src/t1.rs @@ -18,6 +18,40 @@ impl elliptic_curve::Curve for BrainpoolP384t1 { type FieldSize = U32; } +#[cfg(target_pointer_width = "32")] +impl elliptic_curve::Order for BrainpoolP384t1 { + type Limbs = [u32; 12]; + + const ORDER: Self::Limbs = [ + 0xe904_6565, + 0x3b88_3202, + 0x6b7f_c310, + 0xcf3a_b6af, + 0xac04_25a7, + 0x1f16_6e6c, + 0xed54_56b3, + 0x152f_7109, + 0x50e6_41df, + 0x0f5d_6f7e, + 0xa338_6d28, + 0x8cb9_1e82, + ]; +} + +#[cfg(target_pointer_width = "64")] +impl elliptic_curve::Order for BrainpoolP384t1 { + type Limbs = [u64; 6]; + + const ORDER: Self::Limbs = [ + 0x3b88_3202_e904_6565, + 0xcf3a_b6af_6b7f_c310, + 0x1f16_6e6c_ac04_25a7, + 0x152f_7109_ed54_56b3, + 0x0f5d_6f7e_50e6_41df, + 0x8cb9_1e82_a338_6d28, + ]; +} + impl elliptic_curve::weierstrass::Curve for BrainpoolP384t1 {} impl elliptic_curve::weierstrass::PointCompression for BrainpoolP384t1 { diff --git a/k256/Cargo.toml b/k256/Cargo.toml index be2cf3f5..6b0de7c4 100644 --- a/k256/Cargo.toml +++ b/k256/Cargo.toml @@ -18,7 +18,7 @@ keywords = ["bitcoin", "crypto", "ecc", "ethereum", "secp256k1"] [dependencies] cfg-if = "1.0" -elliptic-curve = { version = "0.9", default-features = false, features = ["hazmat"] } +elliptic-curve = { version = "0.9.7", default-features = false, features = ["hazmat"] } hex-literal = { version = "0.3", optional = true } sha2 = { version = "0.9", optional = true, default-features = false } sha3 = { version = "0.9", optional = true, default-features = false } diff --git a/k256/src/arithmetic/scalar/scalar_4x64.rs b/k256/src/arithmetic/scalar/scalar_4x64.rs index 9e73067a..b1856146 100644 --- a/k256/src/arithmetic/scalar/scalar_4x64.rs +++ b/k256/src/arithmetic/scalar/scalar_4x64.rs @@ -1,11 +1,12 @@ //! ProjectiveArithmetic modulo curve base order using 64-bit limbs. //! Ported from -use crate::{FieldBytes, ScalarBits}; +use crate::{FieldBytes, ScalarBits, Secp256k1}; use core::convert::TryInto; use elliptic_curve::{ subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}, util::{adc64, sbb64}, + Order, }; #[cfg(feature = "zeroize")] @@ -13,12 +14,7 @@ use elliptic_curve::zeroize::Zeroize; /// Constant representing the modulus /// n = FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141 -pub const MODULUS: [u64; 4] = [ - 0xBFD2_5E8C_D036_4141, - 0xBAAE_DCE6_AF48_A03B, - 0xFFFF_FFFF_FFFF_FFFE, - 0xFFFF_FFFF_FFFF_FFFF, -]; +pub const MODULUS: [u64; 4] = Secp256k1::ORDER; /// Limbs of 2^256 minus the secp256k1 order. pub const NEG_MODULUS: [u64; 4] = [!MODULUS[0] + 1, !MODULUS[1], !MODULUS[2], !MODULUS[3]]; diff --git a/k256/src/lib.rs b/k256/src/lib.rs index efd4caed..77d8143c 100644 --- a/k256/src/lib.rs +++ b/k256/src/lib.rs @@ -101,6 +101,34 @@ impl elliptic_curve::Curve for Secp256k1 { type FieldSize = U32; } +#[cfg(target_pointer_width = "32")] +impl elliptic_curve::Order for Secp256k1 { + type Limbs = [u32; 8]; + + const ORDER: Self::Limbs = [ + 0xD036_4141, + 0xBFD2_5E8C, + 0xAF48_A03B, + 0xBAAE_DCE6, + 0xFFFF_FFFE, + 0xFFFF_FFFF, + 0xFFFF_FFFF, + 0xFFFF_FFFF, + ]; +} + +#[cfg(target_pointer_width = "64")] +impl elliptic_curve::Order for Secp256k1 { + type Limbs = [u64; 4]; + + const ORDER: Self::Limbs = [ + 0xBFD2_5E8C_D036_4141, + 0xBAAE_DCE6_AF48_A03B, + 0xFFFF_FFFF_FFFF_FFFE, + 0xFFFF_FFFF_FFFF_FFFF, + ]; +} + impl elliptic_curve::weierstrass::Curve for Secp256k1 {} impl elliptic_curve::weierstrass::PointCompression for Secp256k1 { diff --git a/p256/Cargo.toml b/p256/Cargo.toml index ae2be596..1edb82b3 100644 --- a/p256/Cargo.toml +++ b/p256/Cargo.toml @@ -16,7 +16,7 @@ categories = ["cryptography", "no-std"] keywords = ["crypto", "ecc", "nist", "prime256v1", "secp256r1"] [dependencies] -elliptic-curve = { version = "0.9", default-features = false, features = ["hazmat"] } +elliptic-curve = { version = "0.9.7", default-features = false, features = ["hazmat"] } hex-literal = { version = "0.3", optional = true } sha2 = { version = "0.9", optional = true, default-features = false } diff --git a/p256/src/lib.rs b/p256/src/lib.rs index 25dd8501..d420c290 100644 --- a/p256/src/lib.rs +++ b/p256/src/lib.rs @@ -107,6 +107,34 @@ impl elliptic_curve::Curve for NistP256 { type FieldSize = U32; } +#[cfg(target_pointer_width = "32")] +impl elliptic_curve::Order for NistP256 { + type Limbs = [u32; 8]; + + const ORDER: Self::Limbs = [ + 0xfc63_2551, + 0xf3b9_cac2, + 0xa717_9e84, + 0xbce6_faad, + 0xffff_ffff, + 0xffff_ffff, + 0x0000_0000, + 0xffff_ffff, + ]; +} + +#[cfg(target_pointer_width = "64")] +impl elliptic_curve::Order for NistP256 { + type Limbs = [u64; 4]; + + const ORDER: Self::Limbs = [ + 0xf3b9_cac2_fc63_2551, + 0xbce6_faad_a717_9e84, + 0xffff_ffff_ffff_ffff, + 0xffff_ffff_0000_0000, + ]; +} + impl elliptic_curve::weierstrass::Curve for NistP256 {} impl elliptic_curve::weierstrass::PointCompression for NistP256 { diff --git a/p384/Cargo.toml b/p384/Cargo.toml index ee356044..b7a4006f 100644 --- a/p384/Cargo.toml +++ b/p384/Cargo.toml @@ -13,7 +13,7 @@ keywords = ["crypto", "ecc", "nist", "secp384r1"] [dependencies] ecdsa = { version = "=0.11.0-pre.4", optional = true, default-features = false, features = ["der"] } -elliptic-curve = { version = "0.9", default-features = false, features = ["hazmat"] } +elliptic-curve = { version = "0.9.7", default-features = false, features = ["hazmat"] } sha2 = { version = "0.9", optional = true, default-features = false } [features] diff --git a/p384/src/lib.rs b/p384/src/lib.rs index ba5ad9ef..a4c7b9d4 100644 --- a/p384/src/lib.rs +++ b/p384/src/lib.rs @@ -58,6 +58,40 @@ impl elliptic_curve::Curve for NistP384 { impl elliptic_curve::weierstrass::Curve for NistP384 {} +#[cfg(target_pointer_width = "32")] +impl elliptic_curve::Order for NistP384 { + type Limbs = [u32; 12]; + + const ORDER: Self::Limbs = [ + 0xccc5_2973, + 0xecec_196a, + 0x48b0_a77a, + 0x581a_0db2, + 0xf437_2ddf, + 0xc763_4d81, + 0xffff_ffff, + 0xffff_ffff, + 0xffff_ffff, + 0xffff_ffff, + 0xffff_ffff, + 0xffff_ffff, + ]; +} + +#[cfg(target_pointer_width = "64")] +impl elliptic_curve::Order for NistP384 { + type Limbs = [u64; 6]; + + const ORDER: Self::Limbs = [ + 0xecec_196a_ccc5_2973, + 0x581a_0db2_48b0_a77a, + 0xc763_4d81_f437_2ddf, + 0xffff_ffff_ffff_ffff, + 0xffff_ffff_ffff_ffff, + 0xffff_ffff_ffff_ffff, + ]; +} + impl elliptic_curve::weierstrass::PointCompression for NistP384 { const COMPRESS_POINTS: bool = false; }