dcrypt_algorithms/ec/k256/
scalar.rs1use crate::ec::k256::constants::K256_SCALAR_SIZE;
4use crate::error::{validate, Error, Result};
5use dcrypt_common::security::SecretBuffer;
6use dcrypt_internal::zeroing::{Zeroize, ZeroizeOnDrop};
7
8#[derive(Clone, Debug)]
10pub struct Scalar(SecretBuffer<K256_SCALAR_SIZE>);
11
12impl Zeroize for Scalar {
13 fn zeroize(&mut self) {
14 self.0.zeroize();
15 }
16}
17
18impl Drop for Scalar {
19 fn drop(&mut self) {
20 self.zeroize();
21 }
22}
23
24impl ZeroizeOnDrop for Scalar {}
25
26impl Scalar {
27 pub fn new(data: [u8; K256_SCALAR_SIZE]) -> Result<Self> {
32 Self::from_secret_buffer(SecretBuffer::new(data))
33 }
34
35 pub fn from_secret_buffer(buffer: SecretBuffer<K256_SCALAR_SIZE>) -> Result<Self> {
39 Self::validate_canonical_nonzero(buffer.as_ref())?;
40 Ok(Self(buffer))
41 }
42
43 pub fn as_secret_buffer(&self) -> &SecretBuffer<K256_SCALAR_SIZE> {
45 &self.0
46 }
47
48 pub fn serialize(&self) -> SecretBuffer<K256_SCALAR_SIZE> {
50 self.0.clone()
51 }
52
53 pub fn deserialize(bytes: &[u8]) -> Result<Self> {
55 validate::length("K256 Scalar", bytes.len(), K256_SCALAR_SIZE)?;
56 let mut protected = SecretBuffer::zeroed();
57 protected.as_mut().copy_from_slice(bytes);
58 Self::from_secret_buffer(protected)
59 }
60
61 pub fn is_zero(&self) -> bool {
63 let mut any = 0u8;
64 for &byte in self.0.as_ref() {
65 any |= byte;
66 }
67 any == 0
68 }
69
70 fn validate_canonical_nonzero(bytes: &[u8]) -> Result<()> {
71 let mut any = 0u8;
72 for &byte in bytes {
73 any |= byte;
74 }
75 if any == 0 {
76 return Err(Error::param("K256 Scalar", "Scalar cannot be zero"));
77 }
78
79 let mut borrow = 0u8;
80 for i in (0..K256_SCALAR_SIZE).rev() {
81 let (difference, borrow_order) = bytes[i].overflowing_sub(Self::ORDER[i]);
82 let (_, borrow_previous) = difference.overflowing_sub(borrow);
83 borrow = (borrow_order | borrow_previous) as u8;
84 }
85 if borrow == 1 {
86 Ok(())
87 } else {
88 Err(Error::param(
89 "K256 Scalar",
90 "Scalar must be less than the group order",
91 ))
92 }
93 }
94
95 const ORDER: [u8; 32] = [
96 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
97 0xFE, 0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48, 0xA0, 0x3B, 0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36,
98 0x41, 0x41,
99 ];
100}