arcis/utils/crypto/
key.rs

1use crate::{
2    core::circuits::boolean::{
3        boolean_array::BooleanArray,
4        boolean_value::{Boolean, BooleanValue},
5        byte::Byte,
6    },
7    traits::FromLeBytes,
8    utils::matrix::Matrix,
9};
10
11pub const X25519_PRIVATE_KEY_COUNT: usize = 251;
12pub const RESCUE_KEY_COUNT: usize = 5;
13
14/// This is the x25519 public key obtained by a clamped multiplication between the 0-private key
15/// and the generator G. It corresponds to 2^254 * G (hence the logarithm with respect to basis G is
16/// 2^254 mod \ell).
17pub const DEFAULT_MXE_X25519_PUBLIC_KEY: [u8; 32] = [
18    0x2f, 0xe5, 0x7d, 0xa3, 0x47, 0xcd, 0x62, 0x43, 0x15, 0x28, 0xda, 0xac, 0x5f, 0xbb, 0x29, 0x7,
19    0x30, 0xff, 0xf6, 0x84, 0xaf, 0xc4, 0xcf, 0xc2, 0xed, 0x90, 0x99, 0x5f, 0x58, 0xcb, 0x3b, 0x74,
20];
21
22/// The Arcis Rescue key type. A key is an array of length 5 of secret-shared
23/// elements of the finite field with p = 2^255 - 19 elements.
24/// The client rescue key is obtained as
25/// key = rescue_prime_hash(GetSharedSecret(mxe_x25519_private_key, public_key)),
26/// while the mxe rescue key corresponds to 5 randomly generated secret-shared
27/// elements of the field with p elements.
28#[derive(Copy, Clone)]
29pub struct RescueKey<T: Clone + Copy>([T; RESCUE_KEY_COUNT]);
30
31impl<T: Clone + Copy> RescueKey<T> {
32    pub fn new_from_inner(a: [T; RESCUE_KEY_COUNT]) -> Self {
33        Self(a)
34    }
35    pub fn inner(&self) -> [T; RESCUE_KEY_COUNT] {
36        self.0
37    }
38}
39
40impl<T: Clone + Copy> From<RescueKey<T>> for Matrix<T> {
41    fn from(key: RescueKey<T>) -> Self {
42        Matrix::from(key.0.to_vec())
43    }
44}
45
46macro_rules! impl_aes_key {
47    ($t: ident, $byte_len:expr) => {
48        /// The Arcis AES key type.
49        #[derive(Clone)]
50        pub struct $t<B: Boolean>([Byte<B>; $byte_len]);
51
52        impl<B: Boolean> $t<B> {
53            pub fn new_from_inner(a: [Byte<B>; $byte_len]) -> Self {
54                Self(a)
55            }
56            pub fn inner(&self) -> [Byte<B>; $byte_len] {
57                self.0
58            }
59        }
60    };
61}
62
63impl_aes_key!(AES128Key, 16);
64impl_aes_key!(AES192Key, 24);
65impl_aes_key!(AES256Key, 32);
66
67/// The Arcis private key type. A x25519 private key is a random element of the
68/// finite field with ell = 2^252 + 27742317777372353535851937790883648493 elements.
69/// In practice, one would generate the private key as 32 random bytes and then perform
70/// a clamping operation (see e.g. [curve25519-dalek](https://github.com/dalek-cryptography/curve25519-dalek/blob/main/curve25519-dalek/src/scalar.rs#L1386) or [noble-curves](https://github.com/paulmillr/noble-curves/blob/main/src/ed25519.ts#L63))
71/// which essentially results in a key with 251 random bits. For that reason we define the Arcis
72/// private key as 251 secret-shared random bits.
73#[derive(Copy, Clone)]
74pub struct PrivateKey<B: Boolean>([B; X25519_PRIVATE_KEY_COUNT]);
75
76impl<B: Boolean> PrivateKey<B> {
77    pub fn new_from_inner(u: [B; X25519_PRIVATE_KEY_COUNT]) -> Self {
78        Self(u)
79    }
80    pub fn inner(&self) -> [B; X25519_PRIVATE_KEY_COUNT] {
81        self.0
82    }
83}
84
85impl FromLeBytes for PrivateKey<bool> {
86    fn from_le_bytes(bytes: [u8; 32]) -> Self {
87        let bits = bytes
88            .into_iter()
89            .flat_map(|byte| Byte::from(byte).to_vec())
90            .collect::<Vec<bool>>();
91        // the Arcis Private Key are simply the bits 3..254 of the 32-byte random private key
92        PrivateKey::new_from_inner(bits[3..254].to_vec().try_into().unwrap_or_else(
93            |v: Vec<bool>| {
94                panic!(
95                    "Expected a Vec of length {} (found {})",
96                    X25519_PRIVATE_KEY_COUNT,
97                    v.len()
98                )
99            },
100        ))
101    }
102}
103
104impl<const N: usize> From<PrivateKey<BooleanValue>> for PrivateKey<BooleanArray<N>> {
105    fn from(value: PrivateKey<BooleanValue>) -> Self {
106        Self(
107            value
108                .inner()
109                .into_iter()
110                .map(BooleanArray::from)
111                .collect::<Vec<BooleanArray<N>>>()
112                .try_into()
113                .unwrap_or_else(|v: Vec<BooleanArray<N>>| {
114                    panic!("Expected a Vec of length 251 (found {})", v.len())
115                }),
116        )
117    }
118}
119
120/// The Arcis public key type. A public key is a public (i.e., not secret-shared)
121/// element of the finite field with p = 2^255 - 19 elements.
122#[derive(Copy, Clone)]
123pub struct PublicKey<T: Copy>(T);
124
125impl<T: Copy> PublicKey<T> {
126    pub fn new_from_inner(u: T) -> Self {
127        Self(u)
128    }
129    pub fn inner(&self) -> T {
130        self.0
131    }
132}
133
134impl<T: FromLeBytes + Copy> Default for PublicKey<T> {
135    fn default() -> Self {
136        Self(T::from_le_bytes(DEFAULT_MXE_X25519_PUBLIC_KEY))
137    }
138}
139
140// Randomly generated private key (consisting of 32 random bytes)
141pub(crate) const MXE_X25519_PRIVATE_KEY: [u8; 32] = [
142    198, 115, 252, 8, 36, 188, 14, 191, 134, 106, 91, 91, 255, 99, 166, 87, 194, 246, 162, 190,
143    223, 44, 53, 49, 236, 108, 155, 138, 114, 200, 156, 168,
144];
145
146// Five randomly generated elements of the base field.
147pub(crate) const MXE_RESCUE_KEY: [[u8; 32]; 5] = [
148    [
149        124, 219, 118, 100, 151, 174, 173, 201, 180, 159, 95, 202, 109, 154, 90, 104, 99, 221, 206,
150        79, 44, 221, 182, 198, 143, 180, 180, 121, 78, 223, 238, 12,
151    ],
152    [
153        158, 10, 32, 122, 234, 85, 113, 2, 69, 115, 151, 149, 163, 189, 216, 108, 160, 21, 118,
154        154, 185, 199, 198, 251, 142, 193, 168, 98, 218, 59, 20, 9,
155    ],
156    [
157        45, 115, 67, 23, 196, 46, 150, 202, 33, 22, 44, 144, 204, 34, 166, 30, 183, 63, 38, 213,
158        166, 150, 234, 191, 201, 13, 79, 86, 171, 100, 140, 15,
159    ],
160    [
161        209, 1, 108, 251, 175, 105, 199, 246, 83, 186, 72, 0, 15, 236, 105, 110, 5, 109, 41, 216,
162        148, 98, 208, 128, 32, 47, 224, 93, 90, 176, 33, 2,
163    ],
164    [
165        179, 142, 132, 221, 113, 147, 206, 83, 22, 121, 245, 155, 239, 204, 18, 158, 119, 190, 54,
166        17, 28, 17, 247, 191, 151, 147, 118, 151, 38, 169, 21, 4,
167    ],
168];
169
170// 16 randomly generated bytes.
171pub(crate) const MXE_AES128_KEY: [u8; 16] = [
172    124, 219, 118, 100, 151, 174, 173, 201, 180, 159, 95, 202, 109, 154, 90, 104,
173];
174
175// 24 randomly generated bytes.
176pub(crate) const MXE_AES192_KEY: [u8; 24] = [
177    124, 219, 118, 100, 151, 174, 173, 201, 180, 159, 95, 202, 109, 154, 90, 104, 124, 219, 118,
178    100, 151, 174, 173, 201,
179];
180
181// 32 randomly generated bytes.
182pub(crate) const MXE_AES256_KEY: [u8; 32] = [
183    124, 219, 118, 100, 151, 174, 173, 201, 180, 159, 95, 202, 109, 154, 90, 104, 124, 219, 118,
184    100, 151, 174, 173, 201, 180, 159, 95, 202, 109, 154, 90, 104,
185];