• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

tari-project / tari-crypto / 13006565553

28 Jan 2025 08:39AM UTC coverage: 82.022% (-8.8%) from 90.804%
13006565553

push

github

web-flow
feat!: compressed keys (#239)

1 of 419 new or added lines in 6 files covered. (0.24%)

3545 of 4322 relevant lines covered (82.02%)

49.35 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/compressed_commitment.rs
1
// Copyright 2025 The Tari Project
2
// SPDX-License-Identifier: BSD-3-Clause
3

4
//! A commitment is like a sealed envelope. You put some information inside the envelope, and then seal (commit) it.
5
//! You can't change what you've said, but also, no-one knows what you've said until you're ready to open (open) the
6
//! envelope and reveal its contents. Also it's a special envelope that can only be opened by a special opener that
7
//! you keep safe in your drawer.
8

9
use core::{
10
    cmp::Ordering,
11
    hash::{Hash, Hasher},
12
};
13

14
use tari_utilities::{ByteArray, ByteArrayError};
15

16
use crate::{commitment::HomomorphicCommitment, compressed_key::CompressedKey, keys::PublicKey};
17

18
/// There are also different types of commitments that vary in their security guarantees, but all of them are
19
/// represented by binary data; so [HomomorphicCommitment](trait.HomomorphicCommitment.html) implements
20
/// [ByteArray](trait.ByteArray.html).
21
///
22
/// The Homomorphic part means, more or less, that commitments follow some of the standard rules of
23
/// arithmetic. Adding two commitments is the same as committing to the sum of their parts:
24
/// $$ \begin{aligned}
25
///   C_1 &= v_1.H + k_1.G \\\\
26
///   C_2 &= v_2.H + k_2.G \\\\
27
///   \therefore C_1 + C_2 &= (v_1 + v_2)H + (k_1 + k_2)G
28
/// \end{aligned} $$
29
#[derive(Debug, Clone)]
30
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
31
pub struct CompressedCommitment<P>(pub(crate) CompressedKey<P>);
32

33
impl<P: Default + ByteArray + PublicKey> Default for CompressedCommitment<P> {
NEW
34
    fn default() -> Self {
×
NEW
35
        Self(CompressedKey::default())
×
NEW
36
    }
×
37
}
38

39
#[cfg(feature = "borsh")]
40
impl<P: borsh::BorshDeserialize> borsh::BorshDeserialize for CompressedCommitment<P> {
NEW
41
    fn deserialize_reader<R>(reader: &mut R) -> Result<Self, borsh::io::Error>
×
NEW
42
    where R: borsh::io::Read {
×
NEW
43
        Ok(Self(CompressedKey::deserialize_reader(reader)?))
×
NEW
44
    }
×
45
}
46

47
#[cfg(feature = "borsh")]
48
impl<P: borsh::BorshSerialize> borsh::BorshSerialize for CompressedCommitment<P> {
NEW
49
    fn serialize<W: borsh::io::Write>(&self, writer: &mut W) -> borsh::io::Result<()> {
×
NEW
50
        self.0.serialize(writer)
×
NEW
51
    }
×
52
}
53

54
impl<P> CompressedCommitment<P>
55
where P: PublicKey
56
{
57
    /// Get this commitment as a public key point
NEW
58
    pub fn to_public_key(&self) -> Result<P, ByteArrayError> {
×
NEW
59
        self.0.to_public_key()
×
NEW
60
    }
×
61

62
    /// Get this compressed commitment as a homomorphic commitment
NEW
63
    pub fn to_commitment(&self) -> Result<HomomorphicCommitment<P>, ByteArrayError> {
×
NEW
64
        Ok(HomomorphicCommitment(self.to_public_key()?))
×
NEW
65
    }
×
66

67
    /// Get this compressed commitment as a compressed key
NEW
68
    pub fn to_compressed_key(&self) -> CompressedKey<P> {
×
NEW
69
        self.0.clone()
×
NEW
70
    }
×
71

72
    /// Converts a public key into a commitment
NEW
73
    pub fn from_public_key(p: P) -> CompressedCommitment<P> {
×
NEW
74
        let compressed_key = CompressedKey::new_from_pk(p);
×
NEW
75
        CompressedCommitment(compressed_key)
×
NEW
76
    }
×
77

78
    /// Converts a compressed key into a commitment
NEW
79
    pub fn from_compressed_key(compressed_key: CompressedKey<P>) -> Self {
×
NEW
80
        Self(compressed_key)
×
NEW
81
    }
×
82

83
    /// Converts a commitment into a compressed commitment
NEW
84
    pub fn from_commitment(commitment: HomomorphicCommitment<P>) -> Self {
×
NEW
85
        Self(CompressedKey::new_from_pk(commitment.0))
×
NEW
86
    }
×
87
}
88

89
impl<P> ByteArray for CompressedCommitment<P>
90
where P: PublicKey
91
{
NEW
92
    fn from_canonical_bytes(bytes: &[u8]) -> Result<Self, ByteArrayError> {
×
NEW
93
        let key = CompressedKey::from_canonical_bytes(bytes)?;
×
NEW
94
        Ok(Self(key))
×
NEW
95
    }
×
96

NEW
97
    fn as_bytes(&self) -> &[u8] {
×
NEW
98
        self.0.as_bytes()
×
NEW
99
    }
×
100
}
101

102
impl<P> PartialOrd for CompressedCommitment<P>
103
where P: PublicKey
104
{
NEW
105
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
×
NEW
106
        Some(self.cmp(other))
×
NEW
107
    }
×
108
}
109

110
impl<P> Ord for CompressedCommitment<P>
111
where P: PublicKey
112
{
NEW
113
    fn cmp(&self, other: &Self) -> Ordering {
×
NEW
114
        self.0.cmp(&other.0)
×
NEW
115
    }
×
116
}
117

118
impl<P: PublicKey> Hash for CompressedCommitment<P> {
NEW
119
    fn hash<H: Hasher>(&self, state: &mut H) {
×
NEW
120
        state.write(self.as_bytes())
×
NEW
121
    }
×
122
}
123

124
impl<P: PublicKey> PartialEq for CompressedCommitment<P> {
NEW
125
    fn eq(&self, other: &Self) -> bool {
×
NEW
126
        self.0 == other.0
×
NEW
127
    }
×
128
}
129

130
impl<P: PublicKey> Eq for CompressedCommitment<P> {}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc