zkgroup/common/
sho.rs

1//
2// Copyright 2020 Signal Messenger, LLC.
3// SPDX-License-Identifier: AGPL-3.0-only
4//
5
6use curve25519_dalek_signal::ristretto::RistrettoPoint;
7use curve25519_dalek_signal::scalar::Scalar;
8use poksho::shoapi::ShoApiExt as _;
9use poksho::ShoApi;
10
11pub struct Sho {
12    internal_sho: poksho::ShoHmacSha256,
13}
14
15impl Sho {
16    pub fn new(label: &[u8], data: &[u8]) -> Self {
17        let mut sho = poksho::ShoHmacSha256::new(label);
18        sho.absorb_and_ratchet(data);
19        Sho { internal_sho: sho }
20    }
21
22    pub fn absorb_and_ratchet(&mut self, data: &[u8]) {
23        self.internal_sho.absorb_and_ratchet(data)
24    }
25
26    pub fn squeeze(&mut self, outlen: usize) -> Vec<u8> {
27        self.internal_sho.squeeze_and_ratchet(outlen)
28    }
29
30    pub fn squeeze_as_array<const N: usize>(&mut self) -> [u8; N] {
31        self.internal_sho.squeeze_and_ratchet_as_array()
32    }
33
34    pub fn get_point(&mut self) -> RistrettoPoint {
35        RistrettoPoint::from_uniform_bytes(&self.internal_sho.squeeze_and_ratchet_as_array())
36    }
37
38    pub fn get_point_single_elligator(&mut self) -> RistrettoPoint {
39        RistrettoPoint::from_uniform_bytes_single_elligator(
40            &self.internal_sho.squeeze_and_ratchet_as_array(),
41        )
42    }
43
44    pub fn get_scalar(&mut self) -> Scalar {
45        Scalar::from_bytes_mod_order_wide(&self.internal_sho.squeeze_and_ratchet_as_array())
46    }
47}
48
49impl AsMut<poksho::ShoHmacSha256> for Sho {
50    fn as_mut(&mut self) -> &mut poksho::ShoHmacSha256 {
51        &mut self.internal_sho
52    }
53}