cryptography/public_key/
ntru_hrss701.rs1const N: usize = 701;
33const LOGQ: usize = 13;
34const Q: u32 = 1 << LOGQ;
35const Q_MASK: u16 = (Q as u16).wrapping_sub(1);
36
37const PRFKEYBYTES: usize = 32;
38const SHAREDKEYBYTES: usize = 32;
39
40const SAMPLE_IID_BYTES: usize = N - 1; const SAMPLE_FG_BYTES: usize = 2 * SAMPLE_IID_BYTES; const SAMPLE_RM_BYTES: usize = 2 * SAMPLE_IID_BYTES; const PACK_DEG: usize = N - 1; const PACK_TRINARY_BYTES: usize = (PACK_DEG + 4) / 5; const OWCPA_MSGBYTES: usize = 2 * PACK_TRINARY_BYTES; const OWCPA_PUBLICKEYBYTES: usize = (LOGQ * PACK_DEG + 7) / 8; const OWCPA_SECRETKEYBYTES: usize = 2 * PACK_TRINARY_BYTES + OWCPA_PUBLICKEYBYTES; const OWCPA_BYTES: usize = (LOGQ * PACK_DEG + 7) / 8; pub const PUBLIC_KEY_BYTES: usize = OWCPA_PUBLICKEYBYTES; pub const PRIVATE_KEY_BYTES: usize = OWCPA_SECRETKEYBYTES + PRFKEYBYTES; pub const CIPHERTEXT_BYTES: usize = OWCPA_BYTES; pub const SHARED_SECRET_BYTES: usize = SHAREDKEYBYTES; fn poly_lift_hrss(r: &mut [u16; N], a: &[u16; N]) {
64 let t: u16 = (3 - (N % 3)) as u16;
73
74 let mut b = [0u16; N];
76 b[0] = a[0]
77 .wrapping_mul(2u16.wrapping_sub(t))
78 .wrapping_add(a[2].wrapping_mul(t));
79 b[1] = a[1].wrapping_mul(2u16.wrapping_sub(t));
80 b[2] = a[2].wrapping_mul(2u16.wrapping_sub(t));
81
82 let mut zj: u16 = 0; for i in 3..N {
84 b[0] = b[0].wrapping_add(a[i].wrapping_mul(zj.wrapping_add(2 * t)));
85 b[1] = b[1].wrapping_add(a[i].wrapping_mul(zj.wrapping_add(t)));
86 b[2] = b[2].wrapping_add(a[i].wrapping_mul(zj));
87 zj = (zj.wrapping_add(t)) % 3;
92 }
93 b[1] = b[1].wrapping_add(a[0].wrapping_mul(zj.wrapping_add(t)));
94 b[2] = b[2].wrapping_add(a[0].wrapping_mul(zj));
95 b[2] = b[2].wrapping_add(a[1].wrapping_mul(zj.wrapping_add(t)));
96
97 for i in 3..N {
98 b[i] = b[i - 3].wrapping_add(
99 2u16.wrapping_mul(a[i].wrapping_add(a[i - 1]).wrapping_add(a[i - 2])),
100 );
101 }
102
103 crate::public_key::ntru_pqc_shared::poly_mod_3_phi_n::<N>(&mut b);
104 crate::public_key::ntru_pqc_shared::poly_z3_to_zq::<N>(&mut b, Q_MASK);
105
106 r[0] = 0u16.wrapping_sub(b[0]);
108 for i in 0..N - 1 {
109 r[i + 1] = b[i].wrapping_sub(b[i + 1]);
110 }
111}
112
113fn sample_iid_plus(r: &mut [u16; N], uniform_bytes: &[u8]) {
121 debug_assert_eq!(uniform_bytes.len(), SAMPLE_IID_BYTES);
122 crate::public_key::ntru_pqc_shared::sample_iid::<N>(r, uniform_bytes);
123
124 for i in 0..N - 1 {
126 let c = r[i];
127 r[i] = c | (0u16.wrapping_sub(c >> 1));
128 }
129
130 let mut s: u16 = 0;
134 for i in 0..N - 1 {
135 s = s.wrapping_add(r[i + 1].wrapping_mul(r[i]));
136 }
137
138 let s_sign: u16 = 1 | 0u16.wrapping_sub(s >> 15);
140
141 let mut i = 0;
142 while i < N {
143 r[i] = s_sign.wrapping_mul(r[i]);
144 i += 2;
145 }
146
147 for i in 0..N {
149 r[i] = 3 & (r[i] ^ (r[i] >> 15));
150 }
151}
152
153struct Hrss701Variant;
156
157impl crate::public_key::ntru_pqc_shared::NtruVariant<N, LOGQ> for Hrss701Variant {
158 const Q_MASK: u16 = Q_MASK;
159 const WEIGHT: usize = 0;
163 const SAMPLE_FG_BYTES: usize = SAMPLE_FG_BYTES;
164 const SAMPLE_RM_BYTES: usize = SAMPLE_RM_BYTES;
165 const PACK_TRINARY_BYTES: usize = PACK_TRINARY_BYTES;
166 const OWCPA_PUBLICKEYBYTES: usize = OWCPA_PUBLICKEYBYTES;
167 const OWCPA_SECRETKEYBYTES: usize = OWCPA_SECRETKEYBYTES;
168 const OWCPA_BYTES: usize = OWCPA_BYTES;
169 const OWCPA_MSGBYTES: usize = OWCPA_MSGBYTES;
170
171 fn sample_fg(f: &mut [u16; N], g: &mut [u16; N], seed: &[u8]) {
172 debug_assert_eq!(seed.len(), SAMPLE_FG_BYTES);
173 sample_iid_plus(f, &seed[..SAMPLE_IID_BYTES]);
174 sample_iid_plus(g, &seed[SAMPLE_IID_BYTES..]);
175 }
176
177 fn sample_rm(r: &mut [u16; N], m: &mut [u16; N], seed: &[u8]) {
178 debug_assert_eq!(seed.len(), SAMPLE_RM_BYTES);
179 crate::public_key::ntru_pqc_shared::sample_iid::<N>(r, &seed[..SAMPLE_IID_BYTES]);
180 crate::public_key::ntru_pqc_shared::sample_iid::<N>(m, &seed[SAMPLE_IID_BYTES..]);
181 }
182
183 fn update_g_after_z3_to_zq(g: &mut [u16; N]) {
184 for i in (1..N).rev() {
186 g[i] = (3u16).wrapping_mul(g[i - 1].wrapping_sub(g[i]));
187 }
188 g[0] = 0u16.wrapping_sub((3u16).wrapping_mul(g[0]));
189 }
190
191 fn poly_lift(r: &mut [u16; N], a: &[u16; N]) {
192 poly_lift_hrss(r, a);
193 }
194
195 fn check_m(_m: &[u16; N]) -> i32 {
196 0
198 }
199
200 fn poly_sq_tobytes(r: &mut [u8], a: &[u16; N]) {
201 crate::public_key::ntru_pqc_shared::poly_sq_tobytes_logq13::<N>(r, a);
202 }
203
204 fn poly_sq_frombytes(r: &mut [u16; N], a: &[u8]) {
205 crate::public_key::ntru_pqc_shared::poly_sq_frombytes_logq13::<N>(r, a);
206 }
207}
208
209crate::public_key::ntru_pqc_shared::define_pqc_kem! {
212 namespace = NtruHrss701,
213 public_key = NtruHrss701PublicKey,
214 private_key = NtruHrss701PrivateKey,
215 ciphertext = NtruHrss701Ciphertext,
216 shared_secret = NtruHrss701SharedSecret,
217 variant = Hrss701Variant,
218 kat_path = "../../kat/ntruhrss701.rsp",
219}