1use zeroize::Zeroize;
2
3use digest::{
4 typenum::U114, core_api::BlockSizeUser, Update, Output, OutputSizeUser, FixedOutput,
5 ExtendableOutput, XofReader, HashMarker, Digest,
6};
7use sha3::Shake256;
8
9use group::Group;
10use minimal_ed448::{Scalar, Point};
11
12use crate::Ciphersuite;
13
14#[derive(Clone, Default)]
16pub struct Shake256_114(Shake256);
17impl BlockSizeUser for Shake256_114 {
18 type BlockSize = <Shake256 as BlockSizeUser>::BlockSize;
19 fn block_size() -> usize {
20 Shake256::block_size()
21 }
22}
23impl OutputSizeUser for Shake256_114 {
24 type OutputSize = U114;
25 fn output_size() -> usize {
26 114
27 }
28}
29impl Update for Shake256_114 {
30 fn update(&mut self, data: &[u8]) {
31 self.0.update(data);
32 }
33 fn chain(mut self, data: impl AsRef<[u8]>) -> Self {
34 Update::update(&mut self, data.as_ref());
35 self
36 }
37}
38impl FixedOutput for Shake256_114 {
39 fn finalize_fixed(self) -> Output<Self> {
40 let mut res = Default::default();
41 FixedOutput::finalize_into(self, &mut res);
42 res
43 }
44 fn finalize_into(self, out: &mut Output<Self>) {
45 let mut reader = self.0.finalize_xof();
46 reader.read(out);
47 }
48}
49impl HashMarker for Shake256_114 {}
50
51#[derive(Clone, Copy, PartialEq, Eq, Debug, Zeroize)]
57pub struct Ed448;
58impl Ciphersuite for Ed448 {
59 type F = Scalar;
60 type G = Point;
61 type H = Shake256_114;
62
63 const ID: &'static [u8] = b"ed448";
64
65 fn generator() -> Self::G {
66 Point::generator()
67 }
68
69 fn hash_to_F(dst: &[u8], data: &[u8]) -> Self::F {
70 Scalar::wide_reduce(Self::H::digest([dst, data].concat()).as_ref().try_into().unwrap())
71 }
72}
73
74#[test]
75fn test_ed448() {
76 use ff::PrimeField;
77
78 ff_group_tests::group::test_prime_group_bits::<_, Point>(&mut rand_core::OsRng);
79
80 assert_eq!(
83 Ed448::hash_to_F(
84 b"FROST-ED448-SHAKE256-v11nonce",
85 &hex::decode(
86 "\
8789bf16040081ff2990336b200613787937ebe1f024b8cdff90eb6f1c741d91c1\
884a2b2f5858a932ad3d3b18bd16e76ced3070d72fd79ae4402df201f5\
8925e754716a1bc1b87a502297f2a99d89ea054e0018eb55d39562fd01\
9000"
91 )
92 .unwrap()
93 )
94 .to_repr()
95 .to_vec(),
96 hex::decode(
97 "\
9867a6f023e77361707c6e894c625e809e80f33fdb310810053ae29e28\
99e7011f3193b9020e73c183a98cc3a519160ed759376dd92c94831622\
10000"
101 )
102 .unwrap()
103 );
104}