1#[macro_export]
23#[doc(hidden)]
24macro_rules! _array_base {
25 ($name:ident,$l:expr,$t:ty) => {
26 #[allow(non_camel_case_types)]
31 #[derive(Clone, Copy)]
32 pub struct $name(pub [$t; $l]);
33
34 impl $name {
35 #[cfg_attr(feature = "use_attributes", unsafe_hacspec($name))]
36 pub fn new() -> Self {
37 Self([<$t>::default(); $l])
38 }
39
40 #[cfg_attr(feature = "use_attributes", in_hacspec($name))]
41 pub fn length() -> usize {
42 $l
43 }
44
45 #[cfg_attr(feature = "use_attributes", unsafe_hacspec($name))]
46 pub fn from_array(v: [$t; $l]) -> Self {
47 Self(v.clone())
48 }
49
50 #[cfg_attr(feature = "use_attributes", not_hacspec($name))]
51 pub fn from_native_slice(v: &[$t]) -> Self {
52 debug_assert!(v.len() <= $l);
53 let mut tmp = [<$t>::default(); $l];
54 for i in 0..v.len() {
55 tmp[i] = v[i];
56 }
57 Self(tmp.clone())
58 }
59 }
60
61 impl $name {
62 #[cfg_attr(feature = "use_attributes", in_hacspec($name))]
63 pub fn from_slice<A: SeqTrait<$t>>(input: &A, start: usize, len: usize) -> Self {
64 let mut a = Self::new();
65 debug_assert!(len <= a.len(), "{} > {}", len, a.len());
66 a = a.update_slice(0, input, start, len);
67 a
68 }
69
70 #[cfg_attr(feature = "use_attributes", in_hacspec)]
71 pub fn concat<A: SeqTrait<$t>>(&self, next: &A) -> Seq<$t> {
72 let mut out = Seq::new(self.len() + next.len());
73 out = out.update_start(self);
74 out = out.update_slice(self.len(), next, 0, next.len());
75 out
76 }
77
78 #[cfg_attr(feature = "use_attributes", in_hacspec($name))]
79 pub fn from_slice_range<A: SeqTrait<$t>>(input: &A, r: Range<usize>) -> Self {
80 Self::from_slice(input, r.start, r.end - r.start)
81 }
82
83 #[cfg_attr(feature = "use_attributes", in_hacspec($name))]
84 pub fn slice(&self, start_out: usize, len: usize) -> Seq<$t> {
85 Seq::from_slice(self, start_out, len)
86 }
87
88 #[cfg_attr(feature = "use_attributes", in_hacspec($name))]
89 pub fn slice_range(&self, r: Range<usize>) -> Seq<$t> {
90 self.slice(r.start, r.end - r.start)
91 }
92
93 #[cfg_attr(feature = "use_attributes", in_hacspec($name))]
94 pub fn num_chunks(&self, chunk_size: usize) -> usize {
95 (self.len() + chunk_size - 1) / chunk_size
96 }
97
98 #[cfg_attr(feature = "use_attributes", in_hacspec($name))]
99 pub fn get_chunk_len(&self, chunk_size: usize, chunk_number: usize) -> usize {
100 let idx_start = chunk_size * chunk_number;
101 if idx_start + chunk_size > self.len() {
102 self.len() - idx_start
103 } else {
104 chunk_size
105 }
106 }
107
108 #[cfg_attr(feature = "use_attributes", in_hacspec($name))]
109 pub fn get_chunk(&self, chunk_size: usize, chunk_number: usize) -> (usize, Seq<$t>) {
110 let idx_start = chunk_size * chunk_number;
111 let len = self.get_chunk_len(chunk_size, chunk_number);
112 let out = self.slice(idx_start, len);
113 (len, out)
114 }
115
116 #[cfg_attr(feature = "use_attributes", in_hacspec($name))]
117 pub fn set_chunk<A: SeqTrait<$t>>(
118 self,
119 chunk_size: usize,
120 chunk_number: usize,
121 input: &A,
122 ) -> Self {
123 let idx_start = chunk_size * chunk_number;
124 let len = self.get_chunk_len(chunk_size, chunk_number);
125 debug_assert!(
126 input.len() == len,
127 "the chunk length should match the input. got {}, expected {}",
128 input.len(),
129 len
130 );
131 self.update_slice(idx_start, input, 0, len)
132 }
133 }
134
135 impl Default for $name {
136 #[cfg_attr(feature = "use_attributes", in_hacspec($name))]
137 fn default() -> Self {
138 $name::new()
139 }
140 }
141 impl SeqTrait<$t> for $name {
142 #[cfg_attr(feature = "use_attributes", in_hacspec($name))]
143 fn create(x: usize) -> Self {
144 assert_eq!(x, $l);
145 Self::new()
146 }
147
148 #[cfg_attr(feature = "use_attributes", unsafe_hacspec($name))]
149 fn len(&self) -> usize {
150 $l
151 }
152 #[cfg_attr(feature = "use_attributes", not_hacspec($name))]
153 fn iter(&self) -> core::slice::Iter<$t> {
154 self.0.iter()
155 }
156
157 #[cfg_attr(feature = "use_attributes", in_hacspec($name))]
158 fn update_slice<A: SeqTrait<$t>>(
159 mut self,
160 start_out: usize,
161 v: &A,
162 start_in: usize,
163 len: usize,
164 ) -> Self {
165 debug_assert!(self.len() >= start_out + len);
166 debug_assert!(v.len() >= start_in + len);
167 for i in 0..len {
168 self[start_out + i] = v[start_in + i];
169 }
170 self
171 }
172
173 #[cfg_attr(feature = "use_attributes", in_hacspec($name))]
174 fn update<A: SeqTrait<$t>>(self, start: usize, v: &A) -> Self {
175 let len = v.len();
176 self.update_slice(start, v, 0, len)
177 }
178
179 #[cfg_attr(feature = "use_attributes", in_hacspec($name))]
180 fn update_start<A: SeqTrait<$t>>(self, v: &A) -> Self {
181 let len = v.len();
182 self.update_slice(0, v, 0, len)
183 }
184 }
185
186 impl Index<usize> for $name {
187 type Output = $t;
188 #[cfg_attr(feature = "use_attributes", unsafe_hacspec($name))]
189 fn index(&self, i: usize) -> &$t {
190 &self.0[i]
191 }
192 }
193 impl IndexMut<usize> for $name {
194 #[cfg_attr(feature = "use_attributes", unsafe_hacspec($name))]
195 fn index_mut(&mut self, i: usize) -> &mut $t {
196 &mut self.0[i]
197 }
198 }
199
200 impl Index<u8> for $name {
201 type Output = $t;
202 #[cfg_attr(feature = "use_attributes", unsafe_hacspec($name))]
203 fn index(&self, i: u8) -> &$t {
204 &self.0[i as usize]
205 }
206 }
207 impl IndexMut<u8> for $name {
208 #[cfg_attr(feature = "use_attributes", not_hacspec($name))]
209 fn index_mut(&mut self, i: u8) -> &mut $t {
210 &mut self.0[i as usize]
211 }
212 }
213 impl Index<u32> for $name {
214 type Output = $t;
215 #[cfg_attr(feature = "use_attributes", unsafe_hacspec($name))]
216 fn index(&self, i: u32) -> &$t {
217 &self.0[i as usize]
218 }
219 }
220 impl IndexMut<u32> for $name {
221 #[cfg_attr(feature = "use_attributes", not_hacspec($name))]
222 fn index_mut(&mut self, i: u32) -> &mut $t {
223 &mut self.0[i as usize]
224 }
225 }
226 impl Index<i32> for $name {
227 type Output = $t;
228 #[cfg_attr(feature = "use_attributes", unsafe_hacspec($name))]
229 fn index(&self, i: i32) -> &$t {
230 &self.0[i as usize]
231 }
232 }
233 impl IndexMut<i32> for $name {
234 #[cfg_attr(feature = "use_attributes", not_hacspec($name))]
235 fn index_mut(&mut self, i: i32) -> &mut $t {
236 &mut self.0[i as usize]
237 }
238 }
239 impl Index<RangeFull> for $name {
240 type Output = [$t];
241 #[cfg_attr(feature = "use_attributes", unsafe_hacspec($name))]
242 fn index(&self, r: RangeFull) -> &[$t] {
243 &self.0[r]
244 }
245 }
246 impl $name {
247 #[cfg_attr(feature = "use_attributes", not_hacspec($name))]
248 pub fn from_vec(x: Vec<$t>) -> $name {
249 debug_assert_eq!(x.len(), $l);
250 let mut tmp = [<$t>::default(); $l];
251 for (i, e) in x.iter().enumerate() {
252 tmp[i] = *e;
253 }
254 $name(tmp.clone())
255 }
256
257 #[cfg_attr(feature = "use_attributes", in_hacspec($name))]
260 pub fn from_seq<T: SeqTrait<$t>>(x: &T) -> $name {
261 debug_assert_eq!(x.len(), $l);
262 let mut out = $name::new();
263 for i in 0..x.len() {
264 out[i] = x[i];
265 }
266 out
267 }
268 }
269
270 impl $name {
271 fn hex_string_to_vec(s: &str) -> Vec<$t> {
272 debug_assert!(s.len() % core::mem::size_of::<$t>() == 0);
273 let b: Result<Vec<$t>, ParseIntError> = (0..s.len())
274 .step_by(2)
275 .map(|i| u8::from_str_radix(&s[i..i + 2], 16).map(<$t>::from))
276 .collect();
277 b.expect("Error parsing hex string")
278 }
279
280 #[cfg_attr(feature = "use_attributes", unsafe_hacspec($name))]
282 pub fn from_hex(s: &str) -> $name {
283 let v = $name::hex_string_to_vec(s);
284 let mut o = $name::new();
285 debug_assert!(v.len() == $l);
286 for i in 0..$l {
287 o[i] = v[i]
288 }
289 o
290 }
291 }
292 };
293}
294
295#[macro_export]
296macro_rules! generic_array {
297 ($name:ident,$l:expr) => {
298 #[allow(non_camel_case_types)]
303 #[derive(Clone, Copy)]
304 pub struct $name<T>(pub [T; $l]);
305
306 impl<T: Numeric + Copy> $name<T> {
307 #[cfg_attr(feature = "use_attributes", unsafe_hacspec($name))]
308 pub fn new() -> Self {
309 Self([<T>::default(); $l])
310 }
311
312 #[cfg_attr(feature = "use_attributes", in_hacspec($name))]
313 pub fn length() -> usize {
314 $l
315 }
316
317 #[cfg_attr(feature = "use_attributes", unsafe_hacspec($name))]
318 pub fn from_array(v: [T; $l]) -> Self {
319 Self(v.clone())
320 }
321
322 #[cfg_attr(feature = "use_attributes", not_hacspec($name))]
323 pub fn from_native_slice(v: &[T]) -> Self {
324 debug_assert!(v.len() <= $l);
325 let mut tmp = [<T>::default(); $l];
326 for i in 0..v.len() {
327 tmp[i] = v[i];
328 }
329 Self(tmp.clone())
330 }
331 }
332
333 impl<T: Numeric + Copy> $name<T> {
334 #[cfg_attr(feature = "use_attributes", in_hacspec($name))]
335 pub fn from_slice<A: SeqTrait<T>>(input: &A, start: usize, len: usize) -> Self {
336 let mut a = Self::new();
337 debug_assert!(len <= a.len());
338 a = a.update_slice(0, input, start, len);
339 a
340 }
341
342 #[cfg_attr(feature = "use_attributes", in_hacspec)]
343 pub fn concat<A: SeqTrait<T>>(&self, next: &A) -> Seq<T> {
344 let mut out = Seq::new(self.len() + next.len());
345 out = out.update_start(self);
346 out = out.update_slice(self.len(), next, 0, next.len());
347 out
348 }
349
350 #[cfg_attr(feature = "use_attributes", in_hacspec($name))]
351 pub fn from_slice_range<A: SeqTrait<T>>(input: &A, r: Range<usize>) -> Self {
352 Self::from_slice(input, r.start, r.end - r.start)
353 }
354
355 #[cfg_attr(feature = "use_attributes", in_hacspec($name))]
356 pub fn slice(&self, start_out: usize, len: usize) -> Seq<T> {
357 Seq::from_slice(self, start_out, len)
358 }
359
360 #[cfg_attr(feature = "use_attributes", in_hacspec($name))]
361 pub fn slice_range(&self, r: Range<usize>) -> Seq<T> {
362 self.slice(r.start, r.end - r.start)
363 }
364
365 #[cfg_attr(feature = "use_attributes", in_hacspec($name))]
366 pub fn num_chunks(&self, chunk_size: usize) -> usize {
367 (self.len() + chunk_size - 1) / chunk_size
368 }
369
370 #[cfg_attr(feature = "use_attributes", in_hacspec($name))]
371 pub fn get_chunk_len(&self, chunk_size: usize, chunk_number: usize) -> usize {
372 let idx_start = chunk_size * chunk_number;
373 if idx_start + chunk_size > self.len() {
374 self.len() - idx_start
375 } else {
376 chunk_size
377 }
378 }
379
380 #[cfg_attr(feature = "use_attributes", in_hacspec($name))]
381 pub fn get_chunk(&self, chunk_size: usize, chunk_number: usize) -> (usize, Seq<T>) {
382 let idx_start = chunk_size * chunk_number;
383 let len = self.get_chunk_len(chunk_size, chunk_number);
384 let out = self.slice(idx_start, len);
385 (len, out)
386 }
387
388 #[cfg_attr(feature = "use_attributes", in_hacspec($name))]
389 pub fn set_chunk<A: SeqTrait<T>>(
390 self,
391 chunk_size: usize,
392 chunk_number: usize,
393 input: &A,
394 ) -> Self {
395 let idx_start = chunk_size * chunk_number;
396 let len = self.get_chunk_len(chunk_size, chunk_number);
397 debug_assert!(
398 input.len() == len,
399 "the chunk length should match the input. got {}, expected {}",
400 input.len(),
401 len
402 );
403 self.update_slice(idx_start, input, 0, len)
404 }
405 }
406
407 impl<T: Numeric + Copy> Default for $name<T> {
408 #[cfg_attr(feature = "use_attributes", in_hacspec($name))]
409 fn default() -> Self {
410 $name::new()
411 }
412 }
413 impl<T: Numeric + Copy> SeqTrait<T> for $name<T> {
414 #[cfg_attr(feature = "use_attributes", in_hacspec($name))]
415 fn create(x: usize) -> Self {
416 assert_eq!(x, $l);
417 Self::new()
418 }
419
420 #[cfg_attr(feature = "use_attributes", unsafe_hacspec($name))]
421 fn len(&self) -> usize {
422 $l
423 }
424 #[cfg_attr(feature = "use_attributes", not_hacspec($name))]
425 fn iter(&self) -> core::slice::Iter<T> {
426 self.0.iter()
427 }
428
429 #[cfg_attr(feature = "use_attributes", in_hacspec($name))]
430 fn update_slice<A: SeqTrait<T>>(
431 mut self,
432 start_out: usize,
433 v: &A,
434 start_in: usize,
435 len: usize,
436 ) -> Self {
437 debug_assert!(self.len() >= start_out + len);
438 debug_assert!(v.len() >= start_in + len);
439 for i in 0..len {
440 self[start_out + i] = v[start_in + i];
441 }
442 self
443 }
444
445 #[cfg_attr(feature = "use_attributes", in_hacspec($name))]
446 fn update<A: SeqTrait<T>>(self, start: usize, v: &A) -> Self {
447 let len = v.len();
448 self.update_slice(start, v, 0, len)
449 }
450
451 #[cfg_attr(feature = "use_attributes", in_hacspec($name))]
452 fn update_start<A: SeqTrait<T>>(self, v: &A) -> Self {
453 let len = v.len();
454 self.update_slice(0, v, 0, len)
455 }
456 }
457
458 impl<T: Numeric + Copy> Index<usize> for $name<T> {
459 type Output = T;
460 #[cfg_attr(feature = "use_attributes", unsafe_hacspec($name))]
461 fn index(&self, i: usize) -> &T {
462 &self.0[i]
463 }
464 }
465 impl<T: Numeric + Copy> IndexMut<usize> for $name<T> {
466 #[cfg_attr(feature = "use_attributes", unsafe_hacspec($name))]
467 fn index_mut(&mut self, i: usize) -> &mut T {
468 &mut self.0[i]
469 }
470 }
471
472 impl<T: Numeric + Copy> Index<u8> for $name<T> {
473 type Output = T;
474 #[cfg_attr(feature = "use_attributes", unsafe_hacspec($name))]
475 fn index(&self, i: u8) -> &T {
476 &self.0[i as usize]
477 }
478 }
479 impl<T: Numeric + Copy> IndexMut<u8> for $name<T> {
480 #[cfg_attr(feature = "use_attributes", not_hacspec($name))]
481 fn index_mut(&mut self, i: u8) -> &mut T {
482 &mut self.0[i as usize]
483 }
484 }
485 impl<T: Numeric + Copy> Index<u32> for $name<T> {
486 type Output = T;
487 #[cfg_attr(feature = "use_attributes", unsafe_hacspec($name))]
488 fn index(&self, i: u32) -> &T {
489 &self.0[i as usize]
490 }
491 }
492 impl<T: Numeric + Copy> IndexMut<u32> for $name<T> {
493 #[cfg_attr(feature = "use_attributes", not_hacspec($name))]
494 fn index_mut(&mut self, i: u32) -> &mut T {
495 &mut self.0[i as usize]
496 }
497 }
498 impl<T: Numeric + Copy> Index<i32> for $name<T> {
499 type Output = T;
500 #[cfg_attr(feature = "use_attributes", unsafe_hacspec($name))]
501 fn index(&self, i: i32) -> &T {
502 &self.0[i as usize]
503 }
504 }
505 impl<T: Numeric + Copy> IndexMut<i32> for $name<T> {
506 #[cfg_attr(feature = "use_attributes", not_hacspec($name))]
507 fn index_mut(&mut self, i: i32) -> &mut T {
508 &mut self.0[i as usize]
509 }
510 }
511 impl<T: Numeric + Copy> Index<RangeFull> for $name<T> {
512 type Output = [T];
513 #[cfg_attr(feature = "use_attributes", unsafe_hacspec($name))]
514 fn index(&self, r: RangeFull) -> &[T] {
515 &self.0[r]
516 }
517 }
518 impl<T: Numeric + Copy> $name<T> {
519 #[cfg_attr(feature = "use_attributes", not_hacspec($name))]
520 pub fn from_vec(x: Vec<T>) -> $name<T> {
521 debug_assert_eq!(x.len(), $l);
522 let mut tmp = [<T>::default(); $l];
523 for (i, e) in x.iter().enumerate() {
524 tmp[i] = *e;
525 }
526 $name(tmp.clone())
527 }
528
529 #[cfg_attr(feature = "use_attributes", in_hacspec($name))]
532 pub fn from_seq<U: SeqTrait<T>>(x: &U) -> $name<T> {
533 debug_assert_eq!(x.len(), $l);
534 let mut out = $name::new();
535 for i in 0..x.len() {
536 out[i] = x[i];
537 }
538 out
539 }
540 }
541
542 impl<T: Numeric + Copy> fmt::Debug for $name<T> {
544 #[cfg_attr(feature = "use_attributes", not_hacspec($name))]
545 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
546 self.0[..].iter().collect::<Vec<_>>().fmt(f)
547 }
548 }
549 };
550}
551
552#[macro_export]
553#[doc(hidden)]
554macro_rules! _secret_array {
557 ($name:ident,$l:expr,$t:ty, $tbase:ty) => {
558 _array_base!($name, $l, $t);
559
560 impl fmt::Debug for $name {
562 #[cfg_attr(feature = "use_attributes", not_hacspec($name))]
563 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
564 self.0[..]
565 .iter()
566 .map(|x| <$t>::declassify(*x))
567 .collect::<Vec<_>>()
568 .fmt(f)
569 }
570 }
571 impl $name {
573 #[cfg_attr(feature = "use_attributes", unsafe_hacspec($name))]
574 pub fn declassify_eq(&self, other: &Self) -> bool {
575 self.0[..]
576 .iter()
577 .map(|x| <$t>::declassify(*x))
578 .collect::<Vec<_>>()
579 == other.0[..]
580 .iter()
581 .map(|x| <$t>::declassify(*x))
582 .collect::<Vec<_>>()
583 }
584 }
585 impl $name {
586 #[cfg_attr(feature = "use_attributes", unsafe_hacspec)]
587 pub fn to_be_bytes(&self) -> Seq<U8> {
588 const FACTOR: usize = core::mem::size_of::<$t>();
589 let mut out: Seq<U8> = Seq::new($l * FACTOR);
590 for i in 0..$l {
591 let tmp: $t = self[i];
592 let tmp = <$t>::to_be_bytes(&[tmp]);
593 for j in 0..FACTOR {
594 out[i * FACTOR + j] = tmp[j];
595 }
596 }
597 out
598 }
599
600 #[cfg_attr(feature = "use_attributes", unsafe_hacspec($name))]
601 pub fn to_le_bytes(&self) -> Seq<U8> {
602 const FACTOR: usize = core::mem::size_of::<$t>();
603 let mut out: Seq<U8> = Seq::new($l * FACTOR);
604 for i in 0..$l {
605 let tmp: $t = self[i];
606 let tmp = <$t>::to_le_bytes(&[tmp]);
607 for j in 0..FACTOR {
608 out[i * FACTOR + j] = tmp[j];
609 }
610 }
611 out
612 }
613 }
614 impl $name {
615 #[cfg_attr(feature = "use_attributes", not_hacspec($name))]
616 pub fn from_public_slice(v: &[$tbase]) -> $name {
617 debug_assert!(v.len() == $l);
618 Self::from_vec(
619 v[..]
620 .iter()
621 .map(|x| <$t>::classify(*x))
622 .collect::<Vec<$t>>(),
623 )
624 }
625
626 #[cfg_attr(feature = "use_attributes", not_hacspec($name))]
627 pub fn to_public_array(&self) -> [$tbase; $l] {
628 let mut out = [0; $l];
629 for (x, o) in self.0.iter().zip(out.iter_mut()) {
630 *o = <$t>::declassify(*x);
631 }
632 out
633 }
634
635 #[cfg_attr(feature = "use_attributes", not_hacspec($name))]
646 pub fn from_public_array(v: [$tbase; $l]) -> $name {
647 debug_assert!(v.len() == $l);
648 Self::from_vec(
649 v[..]
650 .iter()
651 .map(|x| <$t>::classify(*x))
652 .collect::<Vec<$t>>(),
653 )
654 }
655 }
656 };
657}
658
659#[macro_export]
660#[doc(hidden)]
661macro_rules! _public_array {
662 ($name:ident,$l:expr,$t:ty) => {
663 _array_base!($name, $l, $t);
664
665 impl $name {
666 #[cfg_attr(feature = "use_attributes", unsafe_hacspec($name))]
667 pub fn into_le_bytes(self) -> Seq<u8> {
668 const FACTOR: usize = core::mem::size_of::<$t>();
669 let mut out: Seq<u8> = Seq::new($l * FACTOR);
670 for i in 0..$l {
671 let tmp = <$t>::to_le_bytes(self[i]);
672 for j in 0..FACTOR {
673 out[i * FACTOR + j] = tmp[j];
674 }
675 }
676 out
677 }
678 }
679
680 impl fmt::Debug for $name {
681 #[cfg_attr(feature = "use_attributes", not_hacspec($name))]
682 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
683 self.0[..].fmt(f)
684 }
685 }
686 impl PartialEq for $name {
687 #[cfg_attr(feature = "use_attributes", unsafe_hacspec($name))]
688 fn eq(&self, other: &Self) -> bool {
689 self.0[..] == other.0[..]
690 }
691 }
692 };
693}
694
695#[macro_export]
696#[doc(hidden)]
697macro_rules! _implement_secret_u8_array {
698 ($name:ident, $l:expr) => {
699 _secret_array!($name, $l, U8, u8);
700 _implement_numeric_unsigned_secret!($name, U8);
701
702 impl $name {
703 #[allow(non_snake_case)]
704 #[cfg_attr(feature = "use_attributes", unsafe_hacspec($name))]
705 pub fn to_be_U32s(&self) -> Seq<U32> {
706 let mut out = Seq::new($l / 4);
707 for (i, block) in self.0.chunks(4).enumerate() {
708 debug_assert!(block.len() == 4);
709 out[i] = U32_from_be_bytes(U32Word::from_native_slice(block));
710 }
711 out
712 }
713 #[allow(non_snake_case)]
714 #[cfg_attr(feature = "use_attributes", unsafe_hacspec($name))]
715 pub fn to_le_U32s(&self) -> Seq<U32> {
716 let mut out = Seq::new($l / 4);
717 for (i, block) in self.0.chunks(4).enumerate() {
718 debug_assert!(block.len() == 4);
719 out[i] = U32_from_le_bytes(U32Word::from_native_slice(block));
720 }
721 out
722 }
723 #[allow(non_snake_case)]
724 #[cfg_attr(feature = "use_attributes", unsafe_hacspec($name))]
725 pub fn to_be_U64s(&self) -> Seq<U64> {
726 let mut out = Seq::new($l / 8);
727 for (i, block) in self.0.chunks(8).enumerate() {
728 debug_assert!(block.len() == 8);
729 out[i] = U64_from_be_bytes(U64Word::from_native_slice(block));
730 }
731 out
732 }
733 #[allow(non_snake_case)]
734 #[cfg_attr(feature = "use_attributes", unsafe_hacspec($name))]
735 pub fn to_le_U64s(&self) -> Seq<U64> {
736 let mut out = Seq::new($l / 8);
737 for (i, block) in self.0.chunks(8).enumerate() {
738 debug_assert!(block.len() == 8);
739 out[i] = U64_from_le_bytes(U64Word::from_native_slice(block));
740 }
741 out
742 }
743 #[allow(non_snake_case)]
744 #[cfg_attr(feature = "use_attributes", unsafe_hacspec($name))]
745 pub fn to_U128s_be(&self) -> Seq<U128> {
746 let mut out = Seq::new($l / 16);
747 for (i, block) in self.0.chunks(16).enumerate() {
748 debug_assert!(block.len() == 16);
749 out[i] = U128_from_be_bytes(U128Word::from_native_slice(block));
750 }
751 out
752 }
753 #[allow(non_snake_case)]
754 #[cfg_attr(feature = "use_attributes", unsafe_hacspec($name))]
755 pub fn to_U128s_le(&self) -> Seq<U128> {
756 let mut out = Seq::new($l / 16);
757 for (i, block) in self.0.chunks(16).enumerate() {
758 debug_assert!(block.len() == 16);
759 out[i] = U128_from_le_bytes(U128Word::from_native_slice(block));
760 }
761 out
762 }
763 #[cfg_attr(feature = "use_attributes", not_hacspec($name))]
764 pub fn to_hex(&self) -> String {
765 let strs: Vec<String> = self.0.iter().map(|b| format!("{:02x}", b)).collect();
766 strs.join("")
767 }
768 }
769 };
770}
771
772#[macro_export]
773#[doc(hidden)]
774macro_rules! _implement_public_u8_array {
775 ($name:ident, $l:expr) => {
776 _public_array!($name, $l, u8);
777 _implement_numeric_unsigned_public!($name);
778
779 impl $name {
780 #[cfg_attr(feature = "use_attributes", unsafe_hacspec($name))]
781 pub fn to_be_u32s(&self) -> Seq<u32> {
782 let mut out = Seq::new($l / 4);
783 for (i, block) in self.0.chunks(4).enumerate() {
784 debug_assert!(block.len() == 4);
785 out[i] = u32::from_be_bytes(to_array(block));
786 }
787 out
788 }
789 #[cfg_attr(feature = "use_attributes", unsafe_hacspec($name))]
790 pub fn to_le_u32s(&self) -> Seq<u32> {
791 let mut out = Seq::new($l / 4);
792 for (i, block) in self.0.chunks(4).enumerate() {
793 debug_assert!(block.len() == 4);
794 out[i] = u32::from_le_bytes(to_array(block));
795 }
796 out
797 }
798 #[cfg_attr(feature = "use_attributes", unsafe_hacspec($name))]
799 pub fn to_be_u64s(&self) -> Seq<u64> {
800 let mut out = Seq::new($l / 8);
801 for (i, block) in self.0.chunks(8).enumerate() {
802 debug_assert!(block.len() == 8);
803 out[i] = u64::from_be_bytes(to_array(block));
804 }
805 out
806 }
807 #[cfg_attr(feature = "use_attributes", unsafe_hacspec($name))]
808 pub fn to_le_u64s(&self) -> Seq<u64> {
809 let mut out = Seq::new($l / 8);
810 for (i, block) in self.0.chunks(8).enumerate() {
811 debug_assert!(block.len() == 8);
812 out[i] = u64::from_le_bytes(to_array(block));
813 }
814 out
815 }
816 #[cfg_attr(feature = "use_attributes", unsafe_hacspec($name))]
817 pub fn to_u128s_be(&self) -> Seq<u128> {
818 let mut out = Seq::new($l / 16);
819 for (i, block) in self.0.chunks(16).enumerate() {
820 debug_assert!(block.len() == 16);
821 out[i] = u128::from_be_bytes(to_array(block));
822 }
823 out
824 }
825 #[cfg_attr(feature = "use_attributes", unsafe_hacspec($name))]
826 pub fn to_u128s_le(&self) -> Seq<u128> {
827 let mut out = Seq::new($l / 16);
828 for (i, block) in self.0.chunks(16).enumerate() {
829 debug_assert!(block.len() == 16);
830 out[i] = u128::from_le_bytes(to_array(block));
831 }
832 out
833 }
834 #[cfg_attr(feature = "use_attributes", not_hacspec($name))]
835 pub fn to_hex(&self) -> String {
836 let strs: Vec<String> = self.0.iter().map(|b| format!("{:02x}", b)).collect();
837 strs.join("")
838 }
839 }
840 };
841}
842
843#[macro_export]
846macro_rules! array {
848 ($name:ident, $l:expr, U8) => {
849 _implement_secret_u8_array!($name, $l);
850 };
851 ($name:ident, $l:expr, U8, $idx: ident) => {
852 _implement_secret_u8_array!($name, $l);
853 pub type $idx = usize;
854 };
855 ($name:ident, $l:expr, U16) => {
856 _secret_array!($name, $l, U16, u16);
857 _implement_numeric_unsigned_secret!($name, U16);
858 };
859 ($name:ident, $l:expr, U16, type_for_indexes: $idx: ident) => {
860 _secret_array!($name, $l, U16, u16);
861 _implement_numeric_unsigned_secret!($name, U16);
862 pub type $idx = usize;
863 };
864 ($name:ident, $l:expr, U32) => {
865 _secret_array!($name, $l, U32, u32);
866 _implement_numeric_unsigned_secret!($name, U32);
867 };
868 ($name:ident, $l:expr, U32, type_for_indexes: $idx: ident) => {
869 _secret_array!($name, $l, U32, u32);
870 _implement_numeric_unsigned_secret!($name, U32);
871 pub type $idx = usize;
872 };
873 ($name:ident, $l:expr, U64) => {
874 _secret_array!($name, $l, U64, u64);
875 _implement_numeric_unsigned_secret!($name, U64);
876 };
877 ($name:ident, $l:expr, U64, type_for_indexes: $idx: ident) => {
878 _secret_array!($name, $l, U64, u64);
879 _implement_numeric_unsigned_secret!($name, U64);
880 pub type $idx = usize;
881 };
882 ($name:ident, $l:expr, U128) => {
883 _secret_array!($name, $l, U128, u128);
884 _implement_numeric_unsigned_secret!($name, U128);
885 };
886 ($name:ident, $l:expr, U128, type_for_indexes: $idx: ident) => {
887 _secret_array!($name, $l, U128, u128);
888 _implement_numeric_unsigned_secret!($name, U128);
889 pub type $idx = usize;
890 };
891 ($name:ident, $l:expr, u8) => {
892 _implement_public_u8_array!($name, $l);
893 };
894 ($name:ident, $l:expr, u8, type_for_indexes: $idx: ident) => {
895 _implement_public_u8_array!($name, $l);
896 pub type $idx = usize;
897 };
898 ($name:ident, $l:expr, u16) => {
899 _public_array!($name, $l, u16);
900 _implement_numeric_unsigned_public!($name);
901 };
902 ($name:ident, $l:expr, u16, type_for_indexes: $idx: ident) => {
903 _public_array!($name, $l, u16);
904 _implement_numeric_unsigned_public!($name);
905 pub type $idx = usize;
906 };
907 ($name:ident, $l:expr, u32) => {
908 _public_array!($name, $l, u32);
909 _implement_numeric_unsigned_public!($name);
910 };
911 ($name:ident, $l:expr, u32, type_for_indexes: $idx: ident) => {
912 _public_array!($name, $l, u32);
913 _implement_numeric_unsigned_public!($name);
914 pub type $idx = usize;
915 };
916 ($name:ident, $l:expr, u64) => {
917 _public_array!($name, $l, u64);
918 _implement_numeric_unsigned_public!($name);
919 };
920 ($name:ident, $l:expr, u64, type_for_indexes: $idx: ident) => {
921 _public_array!($name, $l, u64);
922 _implement_numeric_unsigned_public!($name);
923 pub type $idx = usize;
924 };
925 ($name:ident, $l:expr, u128) => {
926 _public_array!($name, $l, u128);
927 _implement_numeric_unsigned_public!($name);
928 };
929 ($name:ident, $l:expr, u128, type_for_indexes: $idx: ident) => {
930 _public_array!($name, $l, u128);
931 _implement_numeric_unsigned_public!($name);
932 pub type $idx = usize;
933 };
934 ($name:ident, $l:expr, $t:ty) => {
935 _public_array!($name, $l, $t);
936 };
937 ($name:ident, $l:expr, $t:ty, type_for_indexes: $idx: ident) => {
938 _public_array!($name, $l, $t);
939 pub type $idx = usize;
940 };
941}
942
943#[macro_export]
944macro_rules! bytes {
947 ($name:ident, $l:expr) => {
948 array!($name, $l, U8);
949 };
950}
951
952#[macro_export]
953macro_rules! public_bytes {
956 ($name:ident, $l:expr) => {
957 array!($name, $l, u8);
958 };
959}
960
961#[macro_export]
962macro_rules! secret_array {
963 ( $int_type: ident, [ $( $x:expr ),+ ] ) => {
964 [
965 $(
966 $int_type($x)
967 ),+
968 ]
969 }
970}
971
972#[macro_export]
973macro_rules! secret_bytes {
974 ([ $( $x:expr ),+ ] ) => {
975 secret_array!(U8, [$($x),+])
976 }
977}
978
979#[macro_export]
980macro_rules! assert_secret_array_eq {
981 ( $a1: expr, $a2: expr, $si: ident) => {
982 assert_eq!(
983 $a1.iter().map(|x| $si::declassify(*x)).collect::<Vec<_>>(),
984 $a2.iter().map(|x| $si::declassify(*x)).collect::<Vec<_>>()
985 );
986 };
987}
988
989#[macro_export]
990macro_rules! assert_bytes_eq {
991 ( $a1: expr, $a2: expr) => {
992 assert_secret_array_eq!($a1, $a2, U8)
993 };
994}
995
996#[macro_export]
997macro_rules! both_arrays {
998 ($public_name:ident, $name:ident, $l:expr, $t:ty, $tbase:ty) => {
999 _secret_array!($name, $l, $t, $tbase);
1000 _public_array!($public_name, $l, $tbase);
1001
1002 impl $name {
1003 #[cfg_attr(feature = "use_attributes", unsafe_hacspec($name))]
1005 pub fn from_public(v: $public_name) -> $name {
1006 Self::from_vec(
1007 v[..]
1008 .iter()
1009 .map(|x| <$t>::classify(*x))
1010 .collect::<Vec<$t>>(),
1011 )
1012 }
1013 }
1014
1015 impl $public_name {
1016 #[cfg_attr(feature = "use_attributes", unsafe_hacspec($name))]
1018 pub fn from_secret_declassify(v: $name) -> $public_name {
1019 Self::from_vec(
1020 v[..]
1021 .iter()
1022 .map(|x| <$t>::declassify(*x))
1023 .collect::<Vec<$tbase>>(),
1024 )
1025 }
1026 }
1027 };
1028}
1029
1030#[macro_export]
1031macro_rules! both_bytes {
1032 ($public_name:ident, $name:ident, $l:expr) => {
1033 both_arrays!($public_name, $name, $l, U8, u8);
1034 };
1035}