1use std::mem;
5
6use k256::{
7 elliptic_curve::{group::GroupEncoding, PrimeField},
8 AffinePoint, NonZeroScalar, ProjectivePoint, Scalar,
9};
10use x25519_dalek::PublicKey;
11
12use sl_mpc_mate::{math::GroupPolynomial, message::*, ByteArray};
13use sl_oblivious::zkproofs::DLogProof;
14
15use crate::setup::{ProtocolParticipant, ABORT_MESSAGE_TAG};
16
17mod encrypted;
18mod scheme;
19mod signed;
20
21pub mod tags;
23
24pub use encrypted::{EncryptedMessage, EncryptionScheme, Scheme};
25pub use signed::SignedMessage;
26pub use tags::{FilteredMsgRelay, Round};
27
28pub type PointBytes = [u8; 33];
30
31pub type ScalarBytes = [u8; 32]; pub use sl_mpc_mate::{
35 coord::Relay,
36 message::{MessageTag, MsgHdr},
37};
38
39pub fn encode_affine(&a: &AffinePoint) -> PointBytes {
41 a.to_bytes().into()
42}
43
44pub fn decode_affine(bytes: &PointBytes) -> Option<AffinePoint> {
46 let mut repr = <AffinePoint as GroupEncoding>::Repr::default();
47 AsMut::<[u8]>::as_mut(&mut repr).copy_from_slice(bytes);
48
49 AffinePoint::from_bytes(&repr).into()
50}
51
52pub fn encode_point(p: &ProjectivePoint) -> PointBytes {
54 encode_affine(&p.to_affine())
55}
56
57pub fn decode_point(bytes: &PointBytes) -> Option<ProjectivePoint> {
59 let mut repr = <ProjectivePoint as GroupEncoding>::Repr::default();
60 AsMut::<[u8]>::as_mut(&mut repr).copy_from_slice(bytes);
61
62 ProjectivePoint::from_bytes(&repr).into()
63}
64
65pub fn encode_scalar(s: &Scalar) -> ScalarBytes {
67 s.to_bytes().into()
68}
69
70pub fn decode_scalar(bytes: &ScalarBytes) -> Option<Scalar> {
72 let mut repr = <Scalar as PrimeField>::Repr::default();
73 AsMut::<[u8]>::as_mut(&mut repr).copy_from_slice(bytes);
74
75 Scalar::from_repr(repr).into()
76}
77
78pub fn decode_nonzero(bytes: &ScalarBytes) -> Option<NonZeroScalar> {
80 NonZeroScalar::new(decode_scalar(bytes)?).into()
81}
82
83pub fn create_abort_message<P>(setup: &P) -> Vec<u8>
85where
86 P: ProtocolParticipant,
87{
88 SignedMessage::<(), _>::new(
89 &setup.msg_id(None, ABORT_MESSAGE_TAG),
90 setup.message_ttl().as_secs() as _,
91 0,
92 0,
93 )
94 .sign(setup.signer())
95}
96
97pub fn check_abort<P: ProtocolParticipant, E>(
99 setup: &P,
100 msg: &[u8],
101 party_id: usize,
102 err: impl FnOnce(usize) -> E,
103) -> Result<(), E> {
104 SignedMessage::<(), _>::verify(msg, setup.verifier(party_id))
105 .map_or(Ok(()), |_| Err(err(party_id)))
106}
107
108pub trait Wrap: Sized {
110 fn external_size(&self) -> usize;
112
113 fn write(&self, buffer: &mut [u8]);
115
116 fn read(buffer: &[u8]) -> Option<Self>;
118
119 fn encode<'a>(&self, buf: &'a mut [u8]) -> &'a mut [u8] {
121 let (buf, rest) = buf.split_at_mut(self.external_size());
122 self.write(buf);
123 rest
124 }
125
126 fn decode(input: &[u8], size: usize) -> Option<(&[u8], Self)> {
129 if input.len() < size {
130 return None;
131 }
132 let (input, rest) = input.split_at(size);
133 Some((rest, Self::read(input)?))
134 }
135}
136
137pub trait FixedExternalSize: Sized {
139 const SIZE: usize;
141}
142
143impl Wrap for () {
144 fn external_size(&self) -> usize {
145 0
146 }
147
148 fn write(&self, _buffer: &mut [u8]) {}
149
150 fn read(_buffer: &[u8]) -> Option<Self> {
151 Some(())
152 }
153}
154
155impl FixedExternalSize for () {
156 const SIZE: usize = 0;
157}
158
159impl<const N: usize> FixedExternalSize for ByteArray<N> {
160 const SIZE: usize = N;
161}
162
163impl<const N: usize> Wrap for ByteArray<N> {
164 fn external_size(&self) -> usize {
165 self.len()
166 }
167
168 fn write(&self, buffer: &mut [u8]) {
169 buffer.copy_from_slice(self);
170 }
171
172 fn read(buffer: &[u8]) -> Option<Self> {
173 let mut value = Self::default();
174 value.copy_from_slice(buffer);
175 Some(value)
176 }
177}
178
179impl Wrap for Scalar {
180 fn external_size(&self) -> usize {
181 mem::size_of::<ScalarBytes>()
182 }
183
184 fn write(&self, buffer: &mut [u8]) {
185 let s = encode_scalar(self);
186 buffer.copy_from_slice(&s);
187 }
188
189 fn read(buffer: &[u8]) -> Option<Self> {
190 decode_scalar(buffer.try_into().ok()?)
191 }
192}
193
194impl Wrap for NonZeroScalar {
195 fn external_size(&self) -> usize {
196 mem::size_of::<ScalarBytes>()
197 }
198
199 fn write(&self, buffer: &mut [u8]) {
200 let s = encode_scalar(self);
201 buffer.copy_from_slice(&s);
202 }
203
204 fn read(buffer: &[u8]) -> Option<Self> {
205 decode_scalar(buffer.try_into().ok()?)
206 .and_then(|s| NonZeroScalar::new(s).into())
207 }
208}
209
210impl Wrap for AffinePoint {
211 fn external_size(&self) -> usize {
212 mem::size_of::<PointBytes>()
213 }
214
215 fn write(&self, buffer: &mut [u8]) {
216 let p = encode_affine(self);
217 buffer.copy_from_slice(&p);
218 }
219
220 fn read(buffer: &[u8]) -> Option<Self> {
221 decode_affine(buffer.try_into().ok()?)
222 }
223}
224
225impl Wrap for ProjectivePoint {
226 fn external_size(&self) -> usize {
227 mem::size_of::<PointBytes>()
228 }
229
230 fn write(&self, buffer: &mut [u8]) {
231 let p = encode_point(self);
232 buffer.copy_from_slice(&p);
233 }
234
235 fn read(buffer: &[u8]) -> Option<Self> {
236 decode_point(buffer.try_into().ok()?)
237 }
238}
239
240impl<const N: usize> Wrap for [u8; N] {
241 fn external_size(&self) -> usize {
242 N
243 }
244
245 fn write(&self, buffer: &mut [u8]) {
246 buffer.copy_from_slice(self);
247 }
248
249 fn read(buffer: &[u8]) -> Option<Self> {
250 let mut value = [0u8; N];
251 value.copy_from_slice(buffer);
252 Some(value)
253 }
254}
255
256impl Wrap for PublicKey {
257 fn external_size(&self) -> usize {
258 32
259 }
260
261 fn write(&self, buffer: &mut [u8]) {
262 buffer.copy_from_slice(self.as_bytes());
263 }
264
265 fn read(buffer: &[u8]) -> Option<Self> {
266 let mut value = [0u8; 32];
267 value.copy_from_slice(buffer);
268 Some(PublicKey::from(value))
269 }
270}
271
272impl Wrap for GroupPolynomial<ProjectivePoint> {
273 fn external_size(&self) -> usize {
274 self.coeffs.len() * mem::size_of::<PointBytes>()
275 }
276
277 fn write(&self, buffer: &mut [u8]) {
278 for (p, b) in self
279 .points()
280 .zip(buffer.chunks_exact_mut(mem::size_of::<PointBytes>()))
281 {
282 b.copy_from_slice(&encode_point(p));
283 }
284 }
285
286 fn read(buffer: &[u8]) -> Option<Self> {
287 buffer
288 .chunks_exact(mem::size_of::<PointBytes>())
289 .map(|p| decode_point(p.try_into().ok()?))
290 .collect::<Option<Vec<ProjectivePoint>>>()
291 .map(GroupPolynomial::new)
292 }
293}
294
295impl FixedExternalSize for DLogProof {
296 const SIZE: usize =
297 mem::size_of::<PointBytes>() + mem::size_of::<ScalarBytes>();
298}
299
300impl Wrap for DLogProof {
301 fn external_size(&self) -> usize {
302 Self::SIZE
303 }
304
305 fn write(&self, buffer: &mut [u8]) {
306 let (t, s) = buffer.split_at_mut(mem::size_of::<PointBytes>());
307
308 self.t.write(t);
309 self.s.write(s);
310 }
311
312 fn read(buffer: &[u8]) -> Option<Self> {
313 let (t, s) = buffer.split_at(mem::size_of::<PointBytes>());
314
315 let t = AffinePoint::read(t)?;
316 let s = Scalar::read(s)?;
317
318 Some(DLogProof { t, s })
319 }
320}
321
322impl Wrap for Vec<u8> {
323 fn external_size(&self) -> usize {
324 self.len()
325 }
326
327 fn write(&self, buffer: &mut [u8]) {
328 buffer.copy_from_slice(self)
329 }
330
331 fn read(buffer: &[u8]) -> Option<Self> {
332 Some(buffer.to_vec())
333 }
334}
335
336impl<T: Wrap + FixedExternalSize> Wrap for Vec<T> {
337 fn external_size(&self) -> usize {
338 self.len() * T::SIZE
339 }
340
341 fn write(&self, buffer: &mut [u8]) {
342 for (v, b) in self.iter().zip(buffer.chunks_exact_mut(T::SIZE)) {
343 v.write(b);
344 }
345 }
346
347 fn read(buffer: &[u8]) -> Option<Self> {
348 buffer
349 .chunks_exact(T::SIZE)
350 .map(T::read)
351 .collect::<Option<Vec<T>>>()
352 }
353}
354
355impl Wrap for u8 {
356 fn external_size(&self) -> usize {
357 1
358 }
359
360 fn write(&self, buffer: &mut [u8]) {
361 buffer[0] = *self;
362 }
363
364 fn read(buffer: &[u8]) -> Option<Self> {
365 buffer.first().copied()
366 }
367}
368
369impl Wrap for u16 {
370 fn external_size(&self) -> usize {
371 2
372 }
373
374 fn write(&self, buffer: &mut [u8]) {
375 buffer[..2].copy_from_slice(&self.to_le_bytes());
376 }
377
378 fn read(buffer: &[u8]) -> Option<Self> {
379 Some(u16::from_le_bytes(buffer.get(..2)?.try_into().unwrap()))
380 }
381}