1use curve25519_dalek_signal::ristretto::RistrettoPoint;
7use curve25519_dalek_signal::scalar::Scalar;
8use poksho::ShoApi;
9use poksho::shoapi::ShoApiExt as _;
10
11#[derive(Clone)]
12pub struct Sho {
13 internal_sho: poksho::ShoHmacSha256,
14}
15
16impl Sho {
17 pub fn new(label: &[u8], data: &[u8]) -> Self {
22 let mut sho = Self::new_seed(label);
23 sho.absorb_and_ratchet(data);
24 sho
25 }
26
27 pub fn new_seed(label: &[u8]) -> Self {
28 let sho = poksho::ShoHmacSha256::new(label);
29 Sho { internal_sho: sho }
30 }
31
32 pub fn absorb_and_ratchet(&mut self, data: &[u8]) {
33 self.internal_sho.absorb_and_ratchet(data)
34 }
35
36 pub fn squeeze(&mut self, outlen: usize) -> Vec<u8> {
37 self.internal_sho.squeeze_and_ratchet(outlen)
38 }
39
40 pub fn squeeze_as_array<const N: usize>(&mut self) -> [u8; N] {
41 self.internal_sho.squeeze_and_ratchet_as_array()
42 }
43
44 pub fn get_point(&mut self) -> RistrettoPoint {
45 RistrettoPoint::from_uniform_bytes(&self.internal_sho.squeeze_and_ratchet_as_array())
46 }
47
48 pub fn get_point_single_elligator(&mut self) -> RistrettoPoint {
49 RistrettoPoint::from_uniform_bytes_single_elligator(
50 &self.internal_sho.squeeze_and_ratchet_as_array(),
51 )
52 }
53
54 pub fn get_scalar(&mut self) -> Scalar {
55 Scalar::from_bytes_mod_order_wide(&self.internal_sho.squeeze_and_ratchet_as_array())
56 }
57}
58
59impl AsMut<poksho::ShoHmacSha256> for Sho {
60 fn as_mut(&mut self) -> &mut poksho::ShoHmacSha256 {
61 &mut self.internal_sho
62 }
63}