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;
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}