1use core::borrow::{Borrow, BorrowMut};
2use core::mem::size_of;
3
4#[repr(C)]
12pub struct Poseidon2Cols<
13 T,
14 const WIDTH: usize,
15 const SBOX_DEGREE: u64,
16 const SBOX_REGISTERS: usize,
17 const HALF_FULL_ROUNDS: usize,
18 const PARTIAL_ROUNDS: usize,
19> {
20 pub export: T,
21
22 pub inputs: [T; WIDTH],
23
24 pub beginning_full_rounds: [FullRound<T, WIDTH, SBOX_DEGREE, SBOX_REGISTERS>; HALF_FULL_ROUNDS],
26
27 pub partial_rounds: [PartialRound<T, WIDTH, SBOX_DEGREE, SBOX_REGISTERS>; PARTIAL_ROUNDS],
29
30 pub ending_full_rounds: [FullRound<T, WIDTH, SBOX_DEGREE, SBOX_REGISTERS>; HALF_FULL_ROUNDS],
32}
33
34#[repr(C)]
36pub struct FullRound<T, const WIDTH: usize, const SBOX_DEGREE: u64, const SBOX_REGISTERS: usize> {
37 pub sbox: [SBox<T, SBOX_DEGREE, SBOX_REGISTERS>; WIDTH],
39 pub post: [T; WIDTH],
41}
42
43#[repr(C)]
45pub struct PartialRound<T, const WIDTH: usize, const SBOX_DEGREE: u64, const SBOX_REGISTERS: usize>
46{
47 pub sbox: SBox<T, SBOX_DEGREE, SBOX_REGISTERS>,
49 pub post_sbox: T,
51}
52
53#[repr(C)]
60pub struct SBox<T, const DEGREE: u64, const REGISTERS: usize>(pub [T; REGISTERS]);
61
62pub const fn num_cols<
63 const WIDTH: usize,
64 const SBOX_DEGREE: u64,
65 const SBOX_REGISTERS: usize,
66 const HALF_FULL_ROUNDS: usize,
67 const PARTIAL_ROUNDS: usize,
68>() -> usize {
69 size_of::<Poseidon2Cols<u8, WIDTH, SBOX_DEGREE, SBOX_REGISTERS, HALF_FULL_ROUNDS, PARTIAL_ROUNDS>>(
70 )
71}
72
73pub const fn make_col_map<
74 const WIDTH: usize,
75 const SBOX_DEGREE: u64,
76 const SBOX_REGISTERS: usize,
77 const HALF_FULL_ROUNDS: usize,
78 const PARTIAL_ROUNDS: usize,
79>() -> Poseidon2Cols<usize, WIDTH, SBOX_DEGREE, SBOX_REGISTERS, HALF_FULL_ROUNDS, PARTIAL_ROUNDS> {
80 todo!()
81 }
99
100impl<
101 T,
102 const WIDTH: usize,
103 const SBOX_DEGREE: u64,
104 const SBOX_REGISTERS: usize,
105 const HALF_FULL_ROUNDS: usize,
106 const PARTIAL_ROUNDS: usize,
107 > Borrow<Poseidon2Cols<T, WIDTH, SBOX_DEGREE, SBOX_REGISTERS, HALF_FULL_ROUNDS, PARTIAL_ROUNDS>>
108 for [T]
109{
110 fn borrow(
111 &self,
112 ) -> &Poseidon2Cols<T, WIDTH, SBOX_DEGREE, SBOX_REGISTERS, HALF_FULL_ROUNDS, PARTIAL_ROUNDS>
113 {
114 let (prefix, shorts, suffix) = unsafe {
116 self.align_to::<Poseidon2Cols<
117 T,
118 WIDTH,
119 SBOX_DEGREE,
120 SBOX_REGISTERS,
121 HALF_FULL_ROUNDS,
122 PARTIAL_ROUNDS,
123 >>()
124 };
125 debug_assert!(prefix.is_empty(), "Alignment should match");
126 debug_assert!(suffix.is_empty(), "Alignment should match");
127 debug_assert_eq!(shorts.len(), 1);
128 &shorts[0]
129 }
130}
131
132impl<
133 T,
134 const WIDTH: usize,
135 const SBOX_DEGREE: u64,
136 const SBOX_REGISTERS: usize,
137 const HALF_FULL_ROUNDS: usize,
138 const PARTIAL_ROUNDS: usize,
139 >
140 BorrowMut<
141 Poseidon2Cols<T, WIDTH, SBOX_DEGREE, SBOX_REGISTERS, HALF_FULL_ROUNDS, PARTIAL_ROUNDS>,
142 > for [T]
143{
144 fn borrow_mut(
145 &mut self,
146 ) -> &mut Poseidon2Cols<T, WIDTH, SBOX_DEGREE, SBOX_REGISTERS, HALF_FULL_ROUNDS, PARTIAL_ROUNDS>
147 {
148 let (prefix, shorts, suffix) = unsafe {
150 self.align_to_mut::<Poseidon2Cols<
151 T,
152 WIDTH,
153 SBOX_DEGREE,
154 SBOX_REGISTERS,
155 HALF_FULL_ROUNDS,
156 PARTIAL_ROUNDS,
157 >>()
158 };
159 debug_assert!(prefix.is_empty(), "Alignment should match");
160 debug_assert!(suffix.is_empty(), "Alignment should match");
161 debug_assert_eq!(shorts.len(), 1);
162 &mut shorts[0]
163 }
164}