zkgroup/crypto/
receipt_credential_request.rs

1//
2// Copyright 2021 Signal Messenger, LLC.
3// SPDX-License-Identifier: AGPL-3.0-only
4//
5
6#![allow(non_snake_case)]
7
8use curve25519_dalek_signal::constants::RISTRETTO_BASEPOINT_POINT;
9use curve25519_dalek_signal::ristretto::RistrettoPoint;
10use curve25519_dalek_signal::scalar::Scalar;
11use partial_default::PartialDefault;
12use serde::{Deserialize, Serialize};
13
14use crate::common::sho::Sho;
15use crate::crypto::credentials;
16use crate::crypto::credentials::{BlindedReceiptCredential, ReceiptCredential};
17use crate::ReceiptSerialBytes;
18
19#[derive(Copy, Clone, PartialEq, Eq, Serialize, Deserialize, PartialDefault)]
20pub struct KeyPair {
21    // private
22    pub(crate) y: Scalar,
23
24    // public
25    pub(crate) Y: RistrettoPoint,
26}
27
28#[derive(Copy, Clone, PartialEq, Eq, Serialize, Deserialize, PartialDefault)]
29pub struct PublicKey {
30    pub(crate) Y: RistrettoPoint,
31}
32
33#[derive(Copy, Clone, PartialEq, Eq, Serialize, Deserialize, PartialDefault)]
34pub struct CiphertextWithSecretNonce {
35    pub(crate) r1: Scalar,
36    pub(crate) D1: RistrettoPoint,
37    pub(crate) D2: RistrettoPoint,
38}
39
40#[derive(Copy, Clone, PartialEq, Eq, Serialize, Deserialize, PartialDefault)]
41pub struct Ciphertext {
42    pub(crate) D1: RistrettoPoint,
43    pub(crate) D2: RistrettoPoint,
44}
45
46impl KeyPair {
47    pub fn generate(sho: &mut Sho) -> Self {
48        let y = sho.get_scalar();
49        let Y = y * RISTRETTO_BASEPOINT_POINT;
50        KeyPair { y, Y }
51    }
52
53    pub fn get_public_key(&self) -> PublicKey {
54        PublicKey { Y: self.Y }
55    }
56
57    pub fn encrypt(
58        &self,
59        receipt_serial_bytes: ReceiptSerialBytes,
60        sho: &mut Sho,
61    ) -> CiphertextWithSecretNonce {
62        let M2 = credentials::convert_to_point_M2_receipt_serial_bytes(receipt_serial_bytes);
63        let r1 = sho.get_scalar();
64        let D1 = r1 * RISTRETTO_BASEPOINT_POINT;
65        let D2 = r1 * (self.Y) + M2;
66
67        CiphertextWithSecretNonce { r1, D1, D2 }
68    }
69
70    pub fn decrypt_blinded_receipt_credential(
71        &self,
72        blinded_receipt_credential: BlindedReceiptCredential,
73    ) -> ReceiptCredential {
74        let V = blinded_receipt_credential.S2 - self.y * blinded_receipt_credential.S1;
75        ReceiptCredential {
76            t: blinded_receipt_credential.t,
77            U: blinded_receipt_credential.U,
78            V,
79        }
80    }
81}
82
83impl CiphertextWithSecretNonce {
84    pub fn get_ciphertext(&self) -> Ciphertext {
85        Ciphertext {
86            D1: self.D1,
87            D2: self.D2,
88        }
89    }
90}