atsamd_hal/peripherals/pukcc/
curves.rs

1//! Module that defines curves parametrizations
2
3/// A type representing a standard curve defined by National Institute of
4/// Standards and Technology (variant 256p)
5pub enum Nist256p {}
6
7impl Curve for Nist256p {
8    const MOD_LENGTH: super::c_abi::u2 = 32;
9    const SCALAR_LENGTH: super::c_abi::u2 = 32;
10    const MODULO_P: &'static [u8] = &[
11        0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
12        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
13        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
14    ];
15
16    const A_CURVE: &'static [u8] = &[
17        0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
18        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
19        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC,
20    ];
21
22    const B_CURVE: &'static [u8] = &[
23        0x00, 0x00, 0x00, 0x00, 0x5a, 0xc6, 0x35, 0xd8, 0xaa, 0x3a, 0x93, 0xe7, 0xb3, 0xeb, 0xbd,
24        0x55, 0x76, 0x98, 0x86, 0xbc, 0x65, 0x1d, 0x06, 0xb0, 0xcc, 0x53, 0xb0, 0xf6, 0x3b, 0xce,
25        0x3c, 0x3e, 0x27, 0xd2, 0x60, 0x4b,
26    ];
27
28    const BASE_POINT_A_X: &'static [u8] = &[
29        0x00, 0x00, 0x00, 0x00, 0x6b, 0x17, 0xd1, 0xf2, 0xe1, 0x2c, 0x42, 0x47, 0xf8, 0xbc, 0xe6,
30        0xe5, 0x63, 0xa4, 0x40, 0xf2, 0x77, 0x03, 0x7d, 0x81, 0x2d, 0xeb, 0x33, 0xa0, 0xf4, 0xa1,
31        0x39, 0x45, 0xd8, 0x98, 0xc2, 0x96,
32    ];
33
34    const BASE_POINT_A_Y: &'static [u8] = &[
35        0x00, 0x00, 0x00, 0x00, 0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b, 0x8e, 0xe7, 0xeb,
36        0x4a, 0x7c, 0x0f, 0x9e, 0x16, 0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31, 0x5e, 0xce, 0xcb, 0xb6,
37        0x40, 0x68, 0x37, 0xbf, 0x51, 0xf5,
38    ];
39
40    const BASE_POINT_A_Z: &'static [u8] = &[
41        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
42        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
43        0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
44    ];
45
46    const ORDER_POINT: &'static [u8] = &[
47        0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
48        0xff, 0xff, 0xff, 0xff, 0xff, 0xbc, 0xe6, 0xfa, 0xad, 0xa7, 0x17, 0x9e, 0x84, 0xf3, 0xb9,
49        0xca, 0xc2, 0xfc, 0x63, 0x25, 0x51,
50    ];
51
52    const CNS: &'static [u8] = &[
53        0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
54        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
55        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
56    ];
57}
58
59/// A trait that generalizes over a curve concept.
60///
61/// General equation of a curve is:
62/// `y^2 = x^3 + a*x + b`
63///
64/// Provides all the parametrizations through associated constants.
65///
66/// Associated constant slices must incorporate zero padding required by PUKCC.
67///
68/// Const generics are limited. It is impossible to have const arrays with a
69/// length as a separate const parameter. Therefore slices are used instead and
70/// length verification is moved to runtime ([`Curve::verify_curve`])
71pub trait Curve {
72    /// Length of P modulus (bytes)
73    const MOD_LENGTH: super::c_abi::u2;
74    /// Length of the scalar (bytes)
75    const SCALAR_LENGTH: super::c_abi::u2;
76    /// P modulus parameter
77    /// Length: MOD_LENGTH + 4
78    const MODULO_P: &'static [u8];
79    /// A parameter of a curve
80    /// Length: MOD_LENGTH + 4
81    const A_CURVE: &'static [u8];
82    /// B parameter of a curve
83    /// Length: MOD_LENGTH + 4
84    const B_CURVE: &'static [u8];
85    /// X coordinate of a base point (point of origin on a curve)
86    /// Length: MOD_LENGTH + 4
87    const BASE_POINT_A_X: &'static [u8];
88    /// Y coordinate of a base point (point of origin on a curve)
89    /// Length: MOD_LENGTH + 4
90    const BASE_POINT_A_Y: &'static [u8];
91    /// Z coordinate of a base point (point of origin on a curve)
92    /// It is equal to 1
93    /// Length: MOD_LENGTH + 4
94    const BASE_POINT_A_Z: &'static [u8];
95    /// Order point of the curve
96    /// Length: SCALAR_LENGTH + 4
97    const ORDER_POINT: &'static [u8];
98    /// Modulo reduction constant precalculated with RedMod service in a
99    /// SetupConstant mode
100    ///
101    /// Note:
102    /// That CNS value is for services over prime field: GF(p)
103    /// For polynomials GF(2^n) it has to be generated separately
104    /// Length: SCALAR_LENGTH + 12
105    const CNS: &'static [u8];
106    /// Function that can be used during runtime to verify if a curve is
107    /// correctly defined.
108    ///
109    /// That is:
110    /// - lengths of slices are following the requirements
111    /// - slices are 4 aligned
112    fn verify_curve() -> Result<(), CurveVerificationFailure> {
113        if Self::MOD_LENGTH % 4 != 0 || Self::SCALAR_LENGTH % 4 != 0 {
114            return Err(CurveVerificationFailure::LengthsAreNotAlignedTo4);
115        }
116        if Self::MODULO_P.len() != (Self::MOD_LENGTH + 4).into() {
117            return Err(CurveVerificationFailure::IncorrectSliceLength {
118                faulty_slice: "MODULO_P",
119                expected_length: (Self::MOD_LENGTH + 4).into(),
120                actual_length: Self::MODULO_P.len(),
121            });
122        }
123        if Self::A_CURVE.len() != (Self::MOD_LENGTH + 4).into() {
124            return Err(CurveVerificationFailure::IncorrectSliceLength {
125                faulty_slice: "A_CURVE",
126                expected_length: (Self::MOD_LENGTH + 4).into(),
127                actual_length: Self::A_CURVE.len(),
128            });
129        }
130        if Self::B_CURVE.len() != (Self::MOD_LENGTH + 4).into() {
131            return Err(CurveVerificationFailure::IncorrectSliceLength {
132                faulty_slice: "B_CURVE",
133                expected_length: (Self::MOD_LENGTH + 4).into(),
134                actual_length: Self::B_CURVE.len(),
135            });
136        }
137        if Self::BASE_POINT_A_X.len() != (Self::MOD_LENGTH + 4).into() {
138            return Err(CurveVerificationFailure::IncorrectSliceLength {
139                faulty_slice: "BASE_POINT_A_X",
140                expected_length: (Self::MOD_LENGTH + 4).into(),
141                actual_length: Self::BASE_POINT_A_X.len(),
142            });
143        }
144        if Self::BASE_POINT_A_Y.len() != (Self::MOD_LENGTH + 4).into() {
145            return Err(CurveVerificationFailure::IncorrectSliceLength {
146                faulty_slice: "BASE_POINT_A_Y",
147                expected_length: (Self::MOD_LENGTH + 4).into(),
148                actual_length: Self::BASE_POINT_A_Y.len(),
149            });
150        }
151        if Self::BASE_POINT_A_Z.len() != (Self::MOD_LENGTH + 4).into() {
152            return Err(CurveVerificationFailure::IncorrectSliceLength {
153                faulty_slice: "BASE_POINT_A_Z",
154                expected_length: (Self::MOD_LENGTH + 4).into(),
155                actual_length: Self::BASE_POINT_A_Z.len(),
156            });
157        }
158        if Self::ORDER_POINT.len() != (Self::SCALAR_LENGTH + 4).into() {
159            return Err(CurveVerificationFailure::IncorrectSliceLength {
160                faulty_slice: "ORDER_POINT",
161                expected_length: (Self::SCALAR_LENGTH + 4).into(),
162                actual_length: Self::ORDER_POINT.len(),
163            });
164        }
165        if Self::CNS.len() != (Self::SCALAR_LENGTH + 12).into() {
166            return Err(CurveVerificationFailure::IncorrectSliceLength {
167                faulty_slice: "CNS",
168                expected_length: (Self::SCALAR_LENGTH + 12).into(),
169                actual_length: Self::CNS.len(),
170            });
171        }
172        Ok(())
173    }
174}
175
176/// An error type representing failure modes for a
177/// [`Curve::verify_curve`] function
178#[allow(missing_docs)]
179#[derive(Debug)]
180pub enum CurveVerificationFailure {
181    IncorrectSliceLength {
182        faulty_slice: &'static str,
183        expected_length: usize,
184        actual_length: usize,
185    },
186    LengthsAreNotAlignedTo4,
187}