1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
//! This module provides common types and constants for encrypted transfers.
use crate::{
bulletproofs::range_proof::*,
common::{types::Amount, *},
curve_arithmetic::*,
elgamal::*,
sigma_protocols::{common::*, enc_trans::EncTransResponse},
};
#[derive(Clone, Copy, Serialize, SerdeSerialize, SerdeDeserialize, Debug, Default)]
#[serde(transparent)]
#[repr(transparent)]
/// A sequential index of an incoming encrypted amount on an account.
pub struct EncryptedAmountIndex {
pub index: u64,
}
#[derive(Clone, Copy, Serialize, SerdeSerialize, SerdeDeserialize, Debug, Default)]
#[serde(transparent)]
#[repr(transparent)]
/// An index that represents which encrypted amounts have been combined into an
/// associated encrypted amount.
/// This is in contrast to [EncryptedAmountIndex] which identifies a single
/// encrypted amount (per account).
pub struct EncryptedAmountAggIndex {
pub index: u64,
}
impl From<u64> for EncryptedAmountAggIndex {
fn from(index: u64) -> Self { EncryptedAmountAggIndex { index } }
}
impl From<u64> for EncryptedAmountIndex {
fn from(index: u64) -> Self { EncryptedAmountIndex { index } }
}
#[derive(PartialEq, Eq, Clone, Serialize, SerdeBase16Serialize, Debug)]
/// An encrypted amount, in two chunks in "little endian limbs". That is, the
/// first chunk represents the low 32 bits of an amount, and the second chunk
/// represents the high 32 bits. The JSON serialization of this is just base16
/// encoded serialized chunks.
pub struct EncryptedAmount<C: Curve> {
pub encryptions: [Cipher<C>; 2],
}
impl<C: Curve> AsRef<[Cipher<C>; 2]> for EncryptedAmount<C> {
fn as_ref(&self) -> &[Cipher<C>; 2] { &self.encryptions }
}
impl<C: Curve> AsRef<[Cipher<C>]> for EncryptedAmount<C> {
fn as_ref(&self) -> &[Cipher<C>] { self.encryptions.as_ref() }
}
/// Randomness used when producing an encrypted amount.
pub struct EncryptedAmountRandomness<C: Curve> {
pub randomness: [Randomness<C>; 2],
}
/// An encrypted amount that we know the index of.
#[derive(Serialize, SerdeSerialize, SerdeDeserialize)]
#[serde(bound(serialize = "C: Curve", deserialize = "C: Curve"))]
#[serde(rename_all = "camelCase")]
pub struct IndexedEncryptedAmount<C: Curve> {
/// The actual encrypted amount.
pub encrypted_chunks: EncryptedAmount<C>,
/// Index of the amount on the account.
pub index: EncryptedAmountIndex,
}
/// Size of the chunk for encrypted amounts.
pub const CHUNK_SIZE: ChunkSize = ChunkSize::ThirtyTwo;
/// Data that will go onto an encrypted amount transfer.
#[derive(Serialize, SerdeSerialize, SerdeDeserialize, Clone, Debug)]
#[serde(bound(serialize = "C: Curve", deserialize = "C: Curve"))]
#[serde(rename_all = "camelCase")]
pub struct EncryptedAmountTransferData<C: Curve> {
/// Encryption of the remaining amount.
pub remaining_amount: EncryptedAmount<C>,
/// Amount that will be sent.
pub transfer_amount: EncryptedAmount<C>,
/// The index such that the encrypted amount used in the transfer represents
/// the aggregate of all encrypted amounts with indices < `index` existing
/// on the account at the time. New encrypted amounts can only add new
/// indices.
pub index: EncryptedAmountAggIndex,
/// A collection of all the proofs.
pub proof: EncryptedAmountTransferProof<C>,
}
/// Data that will go onto a secret to public amount transfer.
#[derive(Serialize, SerdeSerialize, SerdeDeserialize, Debug, Clone)]
#[serde(bound(serialize = "C: Curve", deserialize = "C: Curve"))]
#[serde(rename_all = "camelCase")]
pub struct SecToPubAmountTransferData<C: Curve> {
/// Encryption of the remaining amount.
pub remaining_amount: EncryptedAmount<C>,
/// Amount that will be sent.
pub transfer_amount: Amount,
/// The index such that the encrypted amount used in the transfer represents
/// the aggregate of all encrypted amounts with indices < `index` existing
/// on the account at the time. New encrypted amounts can only add new
/// indices.
pub index: EncryptedAmountAggIndex,
/// A collection of all the proofs.
pub proof: SecToPubAmountTransferProof<C>,
}
/// An aggregated encrypted amount with a decrypted plaintext, collecting
/// encrypted amounts with decryption. The only real difference from the above
/// is the meaning of the index field.
#[derive(Serialize, SerdeSerialize, SerdeDeserialize)]
#[serde(bound(serialize = "C: Curve", deserialize = "C: Curve"))]
#[serde(rename_all = "camelCase")]
pub struct AggregatedDecryptedAmount<C: Curve> {
/// The aggregated encrypted amount.
pub agg_encrypted_amount: EncryptedAmount<C>,
/// The plaintext corresponding to the aggregated encrypted amount.
pub agg_amount: Amount,
/// Index such that the `agg_amount` is the sum of all encrypted amounts
/// on an account with indices strictly below `agg_index`.
#[serde(default)]
pub agg_index: EncryptedAmountAggIndex,
}
// # Proof datatypes
/// Proof that an encrypted transfer data is well-formed
#[derive(Serialize, SerdeBase16Serialize, Clone, Debug)]
pub struct EncryptedAmountTransferProof<C: Curve> {
/// Proof that accounting is done correctly, i.e., remaining + transfer is
/// the original amount.
pub accounting: SigmaProof<EncTransResponse<C>>,
/// Proof that the transfered amount is correctly encrypted, i.e., chunks
/// are small enough.
pub transfer_amount_correct_encryption: RangeProof<C>,
/// Proof that the remaining amount is correctly encrypted, i.e, chunks
/// are small enough.
pub remaining_amount_correct_encryption: RangeProof<C>,
}
/// Proof that an encrypted transfer data is well-formed
#[derive(Serialize, SerdeBase16Serialize, Clone, Debug)]
pub struct SecToPubAmountTransferProof<C: Curve> {
/// Proof that accounting is done correctly, i.e., remaining + transfer is
/// the original amount.
pub accounting: SigmaProof<EncTransResponse<C>>,
/// Proof that the remaining amount is correctly encrypted, i.e, chunks
/// small enough.
pub remaining_amount_correct_encryption: RangeProof<C>,
}