secured_cipher/algorithm/poly1305/
core.rs1pub fn calculate_poly1305_h_values(block: &[u8; 16], hibit: u32) -> (u32, u32, u32, u32, u32) {
26 let h0 = u32::from_le_bytes(block[0..4].try_into().unwrap());
27 let h1 = u32::from_le_bytes(block[3..7].try_into().unwrap()) >> 2;
28 let h2 = u32::from_le_bytes(block[6..10].try_into().unwrap()) >> 4;
29 let h3 = u32::from_le_bytes(block[9..13].try_into().unwrap()) >> 6;
30 let h4 = u32::from_le_bytes(block[12..16].try_into().unwrap()) >> 8 | hibit;
31
32 (h0, h1, h2, h3, h4)
33}
34
35pub fn calculate_poly1305_d_values(
49 h0: u32,
50 h1: u32,
51 h2: u32,
52 h3: u32,
53 h4: u32,
54 r0: u32,
55 r1: u32,
56 r2: u32,
57 r3: u32,
58 r4: u32,
59 s1: u32,
60 s2: u32,
61 s3: u32,
62 s4: u32,
63) -> (u64, u64, u64, u64, u64) {
64 let d0 = h0 as u64 * r0 as u64
65 + h1 as u64 * s4 as u64
66 + h2 as u64 * s3 as u64
67 + h3 as u64 * s2 as u64
68 + h4 as u64 * s1 as u64;
69
70 let d1 = h0 as u64 * r1 as u64
71 + h1 as u64 * r0 as u64
72 + h2 as u64 * s4 as u64
73 + h3 as u64 * s3 as u64
74 + h4 as u64 * s2 as u64;
75
76 let d2 = h0 as u64 * r2 as u64
77 + h1 as u64 * r1 as u64
78 + h2 as u64 * r0 as u64
79 + h3 as u64 * s4 as u64
80 + h4 as u64 * s3 as u64;
81
82 let d3 = h0 as u64 * r3 as u64
83 + h1 as u64 * r2 as u64
84 + h2 as u64 * r1 as u64
85 + h3 as u64 * r0 as u64
86 + h4 as u64 * s4 as u64;
87
88 let d4 = h0 as u64 * r4 as u64
89 + h1 as u64 * r3 as u64
90 + h2 as u64 * r2 as u64
91 + h3 as u64 * r1 as u64
92 + h4 as u64 * r0 as u64;
93
94 (d0, d1, d2, d3, d4)
95}
96
97pub fn apply_poly1305_mod_p(
106 hash: &mut [u32; 5],
107 d0: &mut u64,
108 d1: &mut u64,
109 d2: &mut u64,
110 d3: &mut u64,
111 d4: &mut u64,
112) {
113 let mut c = (*d0 >> 26) as u32;
114 hash[0] = (*d0 as u32) & 0x3ff_ffff;
115 *d1 += c as u64;
116
117 c = (*d1 >> 26) as u32;
118 hash[1] = (*d1 as u32) & 0x3ff_ffff;
119 *d2 += c as u64;
120
121 c = (*d2 >> 26) as u32;
122 hash[2] = (*d2 as u32) & 0x3ff_ffff;
123 *d3 += c as u64;
124
125 c = (*d3 >> 26) as u32;
126 hash[3] = (*d3 as u32) & 0x3ff_ffff;
127 *d4 += c as u64;
128
129 c = (*d4 >> 26) as u32;
130 hash[4] = (*d4 as u32) & 0x3ff_ffff;
131 hash[0] += c * 5;
132
133 c = hash[0] >> 26;
134 hash[0] &= 0x3ff_ffff;
135 hash[1] += c;
136}
137
138pub fn finalize_poly1305_hash(hash: &mut [u32; 5]) {
146 let mut c = hash[1] >> 26;
147 hash[1] &= 0x3ff_ffff;
148 hash[2] += c;
149
150 c = hash[2] >> 26;
151 hash[2] &= 0x3ff_ffff;
152 hash[3] += c;
153
154 c = hash[3] >> 26;
155 hash[3] &= 0x3ff_ffff;
156 hash[4] += c;
157
158 c = hash[4] >> 26;
159 hash[4] &= 0x3ff_ffff;
160 hash[0] += c * 5;
161
162 c = hash[0] >> 26;
163 hash[0] &= 0x3ff_ffff;
164 hash[1] += c;
165
166 let mut g0 = hash[0].wrapping_add(5);
167 c = g0 >> 26;
168 g0 &= 0x3ff_ffff;
169
170 let mut g1 = hash[1].wrapping_add(c);
171 c = g1 >> 26;
172 g1 &= 0x3ff_ffff;
173
174 let mut g2 = hash[2].wrapping_add(c);
175 c = g2 >> 26;
176 g2 &= 0x3ff_ffff;
177
178 let mut g3 = hash[3].wrapping_add(c);
179 c = g3 >> 26;
180 g3 &= 0x3ff_ffff;
181
182 let mut g4 = hash[4].wrapping_add(c).wrapping_sub(1 << 26);
183
184 let mut mask = (g4 >> (31 - 1)).wrapping_sub(1);
185 g0 &= mask;
186 g1 &= mask;
187 g2 &= mask;
188 g3 &= mask;
189 g4 &= mask;
190 mask = !mask;
191 hash[0] = (hash[0] & mask) | g0;
192 hash[1] = (hash[1] & mask) | g1;
193 hash[2] = (hash[2] & mask) | g2;
194 hash[3] = (hash[3] & mask) | g3;
195 hash[4] = (hash[4] & mask) | g4;
196
197 hash[0] |= hash[1] << 26;
198 hash[1] = (hash[1] >> 6) | (hash[2] << 20);
199 hash[2] = (hash[2] >> 12) | (hash[3] << 14);
200 hash[3] = (hash[3] >> 18) | (hash[4] << 8);
201}
202
203pub fn apply_poly1305_pad(hash: &mut [u32; 5], pad: [u32; 4]) {
212 let mut f: u64 = hash[0] as u64 + pad[0] as u64;
213 hash[0] = f as u32;
214
215 f = hash[1] as u64 + pad[1] as u64 + (f >> 32);
216 hash[1] = f as u32;
217
218 f = hash[2] as u64 + pad[2] as u64 + (f >> 32);
219 hash[2] = f as u32;
220
221 f = hash[3] as u64 + pad[3] as u64 + (f >> 32);
222 hash[3] = f as u32;
223}
224
225pub fn poly1305_hash_to_tag(hash: &[u32; 5]) -> [u8; 16] {
236 let mut tag = [0u8; 16];
237 tag[0..4].copy_from_slice(&hash[0].to_le_bytes());
238 tag[4..8].copy_from_slice(&hash[1].to_le_bytes());
239 tag[8..12].copy_from_slice(&hash[2].to_le_bytes());
240 tag[12..16].copy_from_slice(&hash[3].to_le_bytes());
241 tag
242}