1use crate::ec::basis::ec_curve_to_basis_2f_to_hint;
5use crate::ec::{EcCurve, EcPoint};
6use crate::fp::{Fp2, FpBackend};
7use crate::params::{Level1, SecurityLevel};
8use crate::precomp::LevelPrecomp;
9use hybrid_array::typenum::Unsigned;
10use hybrid_array::Array;
11
12pub(crate) fn fmt_hex(f: &mut core::fmt::Formatter<'_>, bytes: &[u8]) -> core::fmt::Result {
14 for &b in bytes {
15 write!(f, "{b:02x}")?;
16 }
17 Ok(())
18}
19
20pub(crate) fn fmt_scalar<L>(f: &mut core::fmt::Formatter<'_>, s: &Scalar<L>) -> core::fmt::Result
22where
23 L: FpBackend,
24{
25 for &limb in s.digits.as_slice() {
26 for &b in &limb.to_le_bytes() {
27 write!(f, "{b:02x}")?;
28 }
29 }
30 Ok(())
31}
32
33pub(crate) fn fmt_fp2<L: FpBackend>(
35 f: &mut core::fmt::Formatter<'_>,
36 v: &Fp2<L>,
37) -> core::fmt::Result {
38 fmt_hex(f, &v.encode())
39}
40
41#[derive(Clone)]
46pub struct Scalar<L: SecurityLevel = Level1> {
47 pub(crate) digits: Array<u64, L::MpLimbs>,
48}
49
50impl<L: FpBackend> core::fmt::Debug for Scalar<L> {
51 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
52 f.write_str("Scalar(")?;
53 fmt_scalar(f, self)?;
54 f.write_str(")")
55 }
56}
57
58impl<L: FpBackend> Scalar<L> {
59 #[inline]
60 pub fn digits(&self) -> &[u64] {
61 self.digits.as_slice()
62 }
63}
64
65impl<L: FpBackend> Default for Scalar<L> {
66 fn default() -> Self {
67 Self {
68 digits: Array::default(),
69 }
70 }
71}
72
73#[derive(Clone)]
152pub struct PublicKey<L: SecurityLevel = Level1> {
153 pub(crate) curve: EcCurve<L>,
154 pub(crate) hint_pk: u8,
155}
156
157impl<L: FpBackend> core::fmt::Debug for PublicKey<L> {
158 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
159 f.write_str("PublicKey { curve_a: ")?;
160 fmt_fp2(f, &self.curve.a)?;
161 write!(f, ", hint: 0x{:02x}", self.hint_pk)?;
162 f.write_str(" }")
163 }
164}
165
166impl<L: FpBackend> core::fmt::Display for PublicKey<L> {
167 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
168 fmt_hex(f, &self.to_bytes())
169 }
170}
171
172impl<L: FpBackend> PublicKey<L> {
173 #[doc(hidden)]
174 #[inline]
175 pub fn new(curve: EcCurve<L>, hint_pk: u8) -> Self {
176 Self { curve, hint_pk }
177 }
178
179 #[inline]
180 pub fn curve(&self) -> &EcCurve<L> {
181 &self.curve
182 }
183
184 #[inline]
185 pub fn hint_pk(&self) -> u8 {
186 self.hint_pk
187 }
188}
189
190impl<L: FpBackend> Default for PublicKey<L> {
191 fn default() -> Self {
192 Self {
193 curve: EcCurve::default(),
194 hint_pk: 0,
195 }
196 }
197}
198
199#[derive(Clone)]
258pub struct Signature<L: SecurityLevel = Level1> {
259 pub(crate) e_aux_a: Fp2<L>,
260 pub(crate) backtracking: u8,
261 pub(crate) two_resp_length: u8,
262 pub(crate) mat: [[Scalar<L>; 2]; 2],
263 pub(crate) chall_coeff: Scalar<L>,
264 pub(crate) hint_aux: u8,
265 pub(crate) hint_chall: u8,
266}
267
268impl<L: FpBackend> Signature<L> {
269 #[inline]
270 pub fn e_aux_a(&self) -> &Fp2<L> {
271 &self.e_aux_a
272 }
273
274 #[inline]
275 pub fn backtracking(&self) -> u8 {
276 self.backtracking
277 }
278
279 #[inline]
280 pub fn two_resp_length(&self) -> u8 {
281 self.two_resp_length
282 }
283
284 #[inline]
285 pub fn mat(&self) -> &[[Scalar<L>; 2]; 2] {
286 &self.mat
287 }
288
289 #[inline]
290 pub fn chall_coeff(&self) -> &Scalar<L> {
291 &self.chall_coeff
292 }
293
294 #[inline]
295 pub fn hint_aux(&self) -> u8 {
296 self.hint_aux
297 }
298
299 #[inline]
300 pub fn hint_chall(&self) -> u8 {
301 self.hint_chall
302 }
303}
304
305#[doc(hidden)]
306impl<L: FpBackend> Signature<L> {
307 #[inline]
308 pub fn set_e_aux_a(&mut self, v: Fp2<L>) {
309 self.e_aux_a = v;
310 }
311
312 #[inline]
313 pub fn set_backtracking(&mut self, v: u8) {
314 self.backtracking = v;
315 }
316
317 #[inline]
318 pub fn set_two_resp_length(&mut self, v: u8) {
319 self.two_resp_length = v;
320 }
321
322 #[inline]
323 pub fn set_hint_aux(&mut self, v: u8) {
324 self.hint_aux = v;
325 }
326
327 #[inline]
328 pub fn set_hint_chall(&mut self, v: u8) {
329 self.hint_chall = v;
330 }
331
332 #[inline]
333 pub fn mat_mut(&mut self) -> &mut [[Scalar<L>; 2]; 2] {
334 &mut self.mat
335 }
336
337 #[inline]
338 pub fn chall_coeff_mut(&mut self) -> &mut Scalar<L> {
339 &mut self.chall_coeff
340 }
341
342 #[inline]
343 pub fn scalar_digits_mut(s: &mut Scalar<L>) -> &mut [u64] {
344 s.digits.as_mut_slice()
345 }
346}
347
348impl<L: FpBackend> Default for Signature<L> {
349 fn default() -> Self {
350 Self {
351 e_aux_a: Fp2::zero(),
352 backtracking: 0,
353 two_resp_length: 0,
354 mat: [
355 [Scalar::default(), Scalar::default()],
356 [Scalar::default(), Scalar::default()],
357 ],
358 chall_coeff: Scalar::default(),
359 hint_aux: 0,
360 hint_chall: 0,
361 }
362 }
363}
364
365impl<L: FpBackend> core::fmt::Debug for Signature<L> {
366 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
367 f.write_str("Signature { e_aux_a: ")?;
368 fmt_fp2(f, &self.e_aux_a)?;
369 write!(
370 f,
371 ", bt: {}, trl: {}, mat: [[",
372 self.backtracking, self.two_resp_length
373 )?;
374 fmt_scalar(f, &self.mat[0][0])?;
375 f.write_str(", ")?;
376 fmt_scalar(f, &self.mat[0][1])?;
377 f.write_str("], [")?;
378 fmt_scalar(f, &self.mat[1][0])?;
379 f.write_str(", ")?;
380 fmt_scalar(f, &self.mat[1][1])?;
381 f.write_str("]], chall: ")?;
382 fmt_scalar(f, &self.chall_coeff)?;
383 write!(
384 f,
385 ", hint_aux: 0x{:02x}, hint_chall: 0x{:02x} }}",
386 self.hint_aux, self.hint_chall
387 )
388 }
389}
390
391impl<L: FpBackend> core::fmt::Display for Signature<L> {
392 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
393 fmt_hex(f, &self.to_bytes())
394 }
395}
396
397pub(crate) fn encode_digits(dst: &mut [u8], src: &[u64], nbytes: usize) {
398 let mut pos = 0;
399 for &d in src {
400 if pos >= nbytes {
401 break;
402 }
403 let bytes = d.to_le_bytes();
404 let take = core::cmp::min(8, nbytes - pos);
405 dst[pos..pos + take].copy_from_slice(&bytes[..take]);
406 pos += take;
407 }
408}
409
410pub(crate) fn decode_digits(dst: &mut [u64], src: &[u8], nbytes: usize) {
411 dst.fill(0);
412 for (i, &byte) in src.iter().enumerate().take(nbytes) {
413 let digit_idx = i / 8;
414 let byte_idx = i % 8;
415 if digit_idx < dst.len() {
416 dst[digit_idx] |= (byte as u64) << (byte_idx * 8);
417 }
418 }
419}
420
421pub(crate) fn proj_to_bytes<L: FpBackend>(dst: &mut [u8], x: &Fp2<L>, z: &Fp2<L>) -> usize {
422 let z_inv = z.inv();
423 let affine = x.mul(&z_inv);
424 let enc = affine.encode();
425 let len = enc.len();
426 dst[..len].copy_from_slice(&enc);
427 len
428}
429
430pub(crate) fn proj_from_bytes<L: FpBackend>(
431 x: &mut Fp2<L>,
432 z: &mut Fp2<L>,
433 src: &[u8],
434) -> Result<usize, crate::Error> {
435 let fp2_len = <L as SecurityLevel>::Fp2EncodedBytes::USIZE;
436 *x = Fp2::<L>::decode(&src[..fp2_len]).ok_or(crate::Error::MalformedInput)?;
437 *z = Fp2::one();
438 Ok(fp2_len)
439}
440
441impl<L: FpBackend> PublicKey<L> {
442 pub fn to_bytes(&self) -> Array<u8, L::PkLen> {
444 let mut enc = Array::<u8, L::PkLen>::default();
445 let mut pos = proj_to_bytes::<L>(&mut enc, &self.curve.a, &self.curve.c);
446 enc[pos] = self.hint_pk;
447 pos += 1;
448 debug_assert_eq!(pos, L::PkLen::USIZE);
449 enc
450 }
451
452 pub fn from_bytes(bytes: &[u8]) -> Result<Self, crate::Error>
457 where
458 L: LevelPrecomp,
459 {
460 if bytes.len() != L::PkLen::USIZE {
461 return Err(crate::Error::InvalidLength);
462 }
463 let mut pk = PublicKey::<L>::default();
464 let mut pos = proj_from_bytes::<L>(&mut pk.curve.a, &mut pk.curve.c, bytes)?;
465 pk.hint_pk = bytes[pos];
466 pos += 1;
467 debug_assert_eq!(pos, L::PkLen::USIZE);
468
469 let mut check_curve = pk.curve.clone();
470 let (_, canonical_hint) = ec_curve_to_basis_2f_to_hint::<L>(
471 &mut check_curve,
472 L::F_CHR,
473 L::basis_e0_px_bytes(),
474 L::basis_e0_qx_bytes(),
475 L::p_cofactor_for_2f(),
476 L::p_cofactor_for_2f_bitlength() as usize,
477 L::torsion_even_power(),
478 )
479 .map_err(|()| crate::Error::MalformedInput)?;
480 if pk.hint_pk != canonical_hint {
481 return Err(crate::Error::MalformedInput);
482 }
483
484 Ok(pk)
485 }
486}
487
488impl<L: FpBackend> Signature<L> {
489 fn matrix_entry_bytes() -> usize {
491 (L::E_RSP as usize + 9) / 8
492 }
493
494 fn chall_coeff_bytes() -> usize {
496 L::LAMBDA as usize / 8
497 }
498
499 pub fn to_bytes(&self) -> Array<u8, L::SigLen> {
501 let mut enc = Array::<u8, L::SigLen>::default();
502 let mut pos = 0;
503
504 let fp2_enc = self.e_aux_a.encode();
506 enc[pos..pos + fp2_enc.len()].copy_from_slice(&fp2_enc);
507 pos += fp2_enc.len();
508
509 enc[pos] = self.backtracking;
511 pos += 1;
512 enc[pos] = self.two_resp_length;
513 pos += 1;
514
515 let mat_bytes = Self::matrix_entry_bytes();
517 for row in &self.mat {
518 for entry in row {
519 encode_digits(&mut enc[pos..], entry.digits.as_slice(), mat_bytes);
520 pos += mat_bytes;
521 }
522 }
523
524 let chall_bytes = Self::chall_coeff_bytes();
526 encode_digits(
527 &mut enc[pos..],
528 self.chall_coeff.digits.as_slice(),
529 chall_bytes,
530 );
531 pos += chall_bytes;
532
533 enc[pos] = self.hint_aux;
535 pos += 1;
536 enc[pos] = self.hint_chall;
537 pos += 1;
538
539 debug_assert_eq!(pos, L::SigLen::USIZE);
540 enc
541 }
542
543 pub fn from_bytes(bytes: &[u8]) -> Result<Self, crate::Error> {
545 if bytes.len() != L::SigLen::USIZE {
546 return Err(crate::Error::InvalidLength);
547 }
548
549 let mut sig = Signature::<L>::default();
550 let mut pos = 0;
551
552 let fp2_len = <L as SecurityLevel>::Fp2EncodedBytes::USIZE;
554 sig.e_aux_a =
555 Fp2::decode(&bytes[pos..pos + fp2_len]).ok_or(crate::Error::MalformedInput)?;
556 pos += fp2_len;
557
558 sig.backtracking = bytes[pos];
560 pos += 1;
561 sig.two_resp_length = bytes[pos];
562 pos += 1;
563
564 let mat_bytes = Self::matrix_entry_bytes();
566 for row in sig.mat.iter_mut() {
567 for entry in row.iter_mut() {
568 decode_digits(entry.digits.as_mut_slice(), &bytes[pos..], mat_bytes);
569 pos += mat_bytes;
570 }
571 }
572
573 let chall_bytes = Self::chall_coeff_bytes();
575 decode_digits(
576 sig.chall_coeff.digits.as_mut_slice(),
577 &bytes[pos..],
578 chall_bytes,
579 );
580 pos += chall_bytes;
581
582 sig.hint_aux = bytes[pos];
584 pos += 1;
585 sig.hint_chall = bytes[pos];
586 pos += 1;
587
588 debug_assert_eq!(pos, L::SigLen::USIZE);
589 Ok(sig)
590 }
591}
592
593impl<L: FpBackend + LevelPrecomp> TryFrom<&[u8]> for PublicKey<L> {
594 type Error = crate::Error;
595
596 fn try_from(bytes: &[u8]) -> Result<Self, Self::Error> {
597 Self::from_bytes(bytes)
598 }
599}
600
601impl<L: FpBackend> TryFrom<&[u8]> for Signature<L> {
602 type Error = crate::Error;
603
604 fn try_from(bytes: &[u8]) -> Result<Self, Self::Error> {
605 Self::from_bytes(bytes)
606 }
607}
608
609impl<L: FpBackend> From<Signature<L>> for Array<u8, L::SigLen> {
610 fn from(sig: Signature<L>) -> Self {
611 sig.to_bytes()
612 }
613}
614
615impl<L: FpBackend> signature::SignatureEncoding for Signature<L>
616where
617 Array<u8, L::SigLen>: Send + Sync,
618{
619 type Repr = Array<u8, L::SigLen>;
620}
621
622impl<L: FpBackend + crate::precomp::LevelPrecomp> signature::Verifier<Signature<L>>
623 for PublicKey<L>
624{
625 fn verify(&self, msg: &[u8], sig: &Signature<L>) -> Result<(), signature::Error> {
626 crate::verify::protocols_verify(self, msg, sig).map_err(|_| signature::Error::new())
627 }
628}
629
630pub fn ec_curve_to_bytes<L: FpBackend>(dst: &mut [u8], curve: &EcCurve<L>) -> usize {
632 proj_to_bytes::<L>(dst, &curve.a, &curve.c)
633}
634
635pub fn ec_curve_from_bytes<L: FpBackend>(
637 curve: &mut EcCurve<L>,
638 src: &[u8],
639) -> Result<usize, crate::Error> {
640 *curve = EcCurve::default();
641 proj_from_bytes::<L>(&mut curve.a, &mut curve.c, src)
642}
643
644pub fn ec_point_to_bytes<L: FpBackend>(dst: &mut [u8], point: &EcPoint<L>) -> usize {
646 proj_to_bytes::<L>(dst, &point.x, &point.z)
647}
648
649pub fn ec_point_from_bytes<L: FpBackend>(
651 point: &mut EcPoint<L>,
652 src: &[u8],
653) -> Result<usize, crate::Error> {
654 proj_from_bytes::<L>(&mut point.x, &mut point.z, src)
655}