1use curve25519_dalek_signal::ristretto::RistrettoPoint;
7use curve25519_dalek_signal::scalar::Scalar;
8use poksho::ShoApi;
9
10pub struct Sho {
11 internal_sho: poksho::ShoHmacSha256,
12}
13
14impl Sho {
15 pub fn new(label: &[u8], data: &[u8]) -> Self {
16 let mut sho = poksho::ShoHmacSha256::new(label);
17 sho.absorb_and_ratchet(data);
18 Sho { internal_sho: sho }
19 }
20
21 pub fn absorb_and_ratchet(&mut self, data: &[u8]) {
22 self.internal_sho.absorb_and_ratchet(data)
23 }
24
25 pub fn squeeze(&mut self, outlen: usize) -> Vec<u8> {
26 self.internal_sho.squeeze_and_ratchet(outlen)
27 }
28
29 pub fn get_point(&mut self) -> RistrettoPoint {
30 let mut point_bytes = [0u8; 64];
31 point_bytes.copy_from_slice(&self.internal_sho.squeeze_and_ratchet(64)[..]);
32 RistrettoPoint::from_uniform_bytes(&point_bytes)
33 }
34
35 pub fn get_point_single_elligator(&mut self) -> RistrettoPoint {
36 let mut point_bytes = [0u8; 32];
37 point_bytes.copy_from_slice(&self.internal_sho.squeeze_and_ratchet(32)[..]);
38 RistrettoPoint::from_uniform_bytes_single_elligator(&point_bytes)
39 }
40
41 pub fn get_scalar(&mut self) -> Scalar {
42 let mut scalar_bytes = [0u8; 64];
43 scalar_bytes.copy_from_slice(&self.internal_sho.squeeze_and_ratchet(64)[..]);
44 Scalar::from_bytes_mod_order_wide(&scalar_bytes)
45 }
46}
47
48impl AsMut<poksho::ShoHmacSha256> for Sho {
49 fn as_mut(&mut self) -> &mut poksho::ShoHmacSha256 {
50 &mut self.internal_sho
51 }
52}