dcrypt_algorithms/ec/b283k/
scalar.rs1use crate::ec::b283k::constants::B283K_SCALAR_SIZE;
4use crate::error::{Error, Result};
5use dcrypt_common::security::SecretBuffer;
6use zeroize::{Zeroize, ZeroizeOnDrop};
7
8#[derive(Clone, Zeroize, ZeroizeOnDrop, Debug)]
10pub struct Scalar(SecretBuffer<B283K_SCALAR_SIZE>);
11
12impl Scalar {
13 pub fn new(mut data: [u8; B283K_SCALAR_SIZE]) -> Result<Self> {
19 Self::reduce_scalar_bytes(&mut data)?;
20 Ok(Scalar(SecretBuffer::new(data)))
21 }
22
23 pub fn from_secret_buffer(buffer: SecretBuffer<B283K_SCALAR_SIZE>) -> Result<Self> {
28 let mut bytes = [0u8; B283K_SCALAR_SIZE];
29 bytes.copy_from_slice(buffer.as_ref());
30 Self::reduce_scalar_bytes(&mut bytes)?;
31 Ok(Scalar(SecretBuffer::new(bytes)))
32 }
33
34 pub fn as_secret_buffer(&self) -> &SecretBuffer<B283K_SCALAR_SIZE> {
36 &self.0
37 }
38
39 pub fn serialize(&self) -> [u8; B283K_SCALAR_SIZE] {
41 let mut result = [0u8; B283K_SCALAR_SIZE];
42 result.copy_from_slice(self.0.as_ref());
43 result
44 }
45
46 pub fn is_zero(&self) -> bool {
48 self.0.as_ref().iter().all(|&b| b == 0)
49 }
50
51 fn reduce_scalar_bytes(bytes: &mut [u8; B283K_SCALAR_SIZE]) -> Result<()> {
52 bytes[0] &= 0x01; if bytes.iter().all(|&b| b == 0) {
54 return Err(Error::param("B283k Scalar", "Scalar cannot be zero"));
55 }
56
57 let mut is_ge = false;
58 for (i, (&byte, &order_byte)) in bytes.iter().zip(Self::ORDER.iter()).enumerate() {
59 if byte > order_byte {
60 is_ge = true;
61 break;
62 }
63 if byte < order_byte {
64 break;
65 }
66 if i == B283K_SCALAR_SIZE - 1 {
67 is_ge = true;
68 }
69 }
70
71 if is_ge {
72 let mut borrow = 0i16;
73 for i in (0..B283K_SCALAR_SIZE).rev() {
74 let diff = (bytes[i] as i16) - (Self::ORDER[i] as i16) - borrow;
75 if diff < 0 {
76 bytes[i] = (diff + 256) as u8;
77 borrow = 1;
78 } else {
79 bytes[i] = diff as u8;
80 borrow = 0;
81 }
82 }
83 }
84
85 if bytes.iter().all(|&b| b == 0) {
86 return Err(Error::param(
87 "B283k Scalar",
88 "Reduction resulted in zero scalar",
89 ));
90 }
91 Ok(())
92 }
93
94 const ORDER: [u8; 36] = [
95 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
96 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x96, 0xE4, 0x04, 0x28,
97 0x2D, 0xD3, 0x23, 0x22, 0x83, 0xE5,
98 ];
99}