zkgroup/crypto/
receipt_struct.rs

1//
2// Copyright 2021 Signal Messenger, LLC.
3// SPDX-License-Identifier: AGPL-3.0-only
4//
5
6use curve25519_dalek_signal::scalar::Scalar;
7use serde::{Deserialize, Serialize};
8
9use crate::common::sho::Sho;
10use crate::common::simple_types::{ReceiptLevel, ReceiptSerialBytes, Timestamp};
11
12/// The full set of information known by the client after receiving the credential response from
13/// the issuing server.
14///
15/// This information will all be shared with the credential presentation. Initially the
16/// client only knows the receipt_serial_bytes which is randomly generated. receipt_serial_bytes
17/// should never be shared with the issuing service in unencrypted form.
18///
19/// Clients must do validation on the returned receipt_expiration_time and receipt_level to ensure
20/// no tagging has occurred.
21#[derive(Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]
22pub struct ReceiptStruct {
23    pub(crate) receipt_serial_bytes: ReceiptSerialBytes,
24    pub(crate) receipt_expiration_time: Timestamp,
25    pub(crate) receipt_level: ReceiptLevel,
26}
27
28impl ReceiptStruct {
29    pub fn new(
30        receipt_serial_bytes: ReceiptSerialBytes,
31        receipt_expiration_time: Timestamp,
32        receipt_level: ReceiptLevel,
33    ) -> Self {
34        Self {
35            receipt_serial_bytes,
36            receipt_expiration_time,
37            receipt_level,
38        }
39    }
40
41    pub fn calc_m1(&self) -> Scalar {
42        Self::calc_m1_from(self.receipt_expiration_time, self.receipt_level)
43    }
44
45    pub fn calc_m1_from(receipt_expiration_time: Timestamp, receipt_level: ReceiptLevel) -> Scalar {
46        let mut bytes =
47            [0u8; std::mem::size_of::<Timestamp>() + std::mem::size_of::<ReceiptLevel>()];
48        bytes[..std::mem::size_of::<Timestamp>()]
49            .copy_from_slice(&receipt_expiration_time.to_be_bytes());
50        bytes[std::mem::size_of::<Timestamp>()..].copy_from_slice(&receipt_level.to_be_bytes());
51        let mut sho = Sho::new(b"Signal_ZKGroup_20210919_Receipt_CalcM1", &bytes);
52        sho.get_scalar()
53    }
54}