Skip to content

Commit c92694b

Browse files
committed
confidential: add a bunch of consts and type aliases
More work to make the different confidential types more uniform.
1 parent 2a4ce2d commit c92694b

4 files changed

Lines changed: 101 additions & 77 deletions

File tree

src/confidential/asset.rs

Lines changed: 35 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -13,40 +13,48 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer};
1313
use crate::encode::{self, Decodable, Encodable};
1414
use crate::issuance::AssetId;
1515

16+
type ExplicitInner = AssetId;
17+
type ConfInner = Generator;
18+
19+
const EXPLICIT_LEN: usize = 32;
20+
const CONFIDENTIAL_LEN: usize = 33;
21+
const CONF_PREFIX_1: u8 = 0x0a;
22+
const CONF_PREFIX_2: u8 = 0x0b;
23+
1624
/// A CT commitment to an asset
1725
#[derive(Copy, Clone, Debug, Default, Eq, Hash, PartialEq, PartialOrd, Ord)]
1826
pub enum Asset {
1927
/// No value
2028
#[default]
2129
Null,
2230
/// Asset entropy is explicitly encoded
23-
Explicit(AssetId),
31+
Explicit(ExplicitInner),
2432
/// Asset is committed
25-
Confidential(Generator),
33+
Confidential(ConfInner),
2634
}
2735

2836
impl Asset {
2937
/// Create asset commitment.
3038
pub fn new_confidential<C: Signing>(
3139
secp: &Secp256k1<C>,
3240
asset: AssetId,
33-
bf: AssetBlindingFactor,
41+
bf: BlindingFactor,
3442
) -> Self {
35-
Self::Confidential(Generator::new_blinded(secp, asset.into_tag(), bf.into_inner()))
43+
Self::Confidential(ConfInner::new_blinded(secp, asset.into_tag(), bf.into_inner()))
3644
}
3745

3846
/// Serialized length, in bytes
3947
pub fn encoded_length(&self) -> usize {
4048
match *self {
4149
Self::Null => 1,
42-
Self::Explicit(..) => 33,
43-
Self::Confidential(..) => 33,
50+
Self::Explicit(..) => 1 + EXPLICIT_LEN,
51+
Self::Confidential(..) => CONFIDENTIAL_LEN,
4452
}
4553
}
4654

4755
/// Create from commitment.
4856
pub fn from_commitment(bytes: &[u8]) -> Result<Self, encode::Error> {
49-
Ok(Self::Confidential(Generator::from_slice(bytes)?))
57+
Ok(Self::Confidential(ConfInner::from_slice(bytes)?))
5058
}
5159

5260
/// Check if the object is null.
@@ -60,7 +68,7 @@ impl Asset {
6068

6169
/// Returns the explicit inner value.
6270
/// Returns [None] if [`Self::is_explicit`] returns false.
63-
pub fn explicit(&self) -> Option<AssetId> {
71+
pub fn explicit(&self) -> Option<ExplicitInner> {
6472
match *self {
6573
Self::Explicit(i) => Some(i),
6674
_ => None,
@@ -69,7 +77,7 @@ impl Asset {
6977

7078
/// Returns the confidential commitment in case of a confidential value.
7179
/// Returns [None] if [`Self::is_confidential`] returns false.
72-
pub fn commitment(&self) -> Option<Generator> {
80+
pub fn commitment(&self) -> Option<ConfInner> {
7381
match *self {
7482
Self::Confidential(i) => Some(i),
7583
_ => None,
@@ -84,19 +92,19 @@ impl Asset {
8492
pub fn into_asset_gen<C: secp256k1_zkp::Signing>(
8593
self,
8694
secp: &Secp256k1<C>,
87-
) -> Option<Generator> {
95+
) -> Option<ConfInner> {
8896
match self {
8997
// Only error is Null error which is dealt with later
9098
// when we have more context information about it.
9199
Self::Null => None,
92-
Self::Explicit(x) => Some(Generator::new_unblinded(secp, x.into_tag())),
100+
Self::Explicit(x) => Some(ConfInner::new_unblinded(secp, x.into_tag())),
93101
Self::Confidential(gen) => Some(gen),
94102
}
95103
}
96104
}
97105

98-
impl From<Generator> for Asset {
99-
fn from(from: Generator) -> Self { Self::Confidential(from) }
106+
impl From<ConfInner> for Asset {
107+
fn from(from: ConfInner) -> Self { Self::Confidential(from) }
100108
}
101109

102110
impl fmt::Display for Asset {
@@ -119,7 +127,7 @@ impl Encodable for Asset {
119127
}
120128
Self::Confidential(generator) => {
121129
s.write_all(&generator.serialize())?;
122-
Ok(33)
130+
Ok(CONFIDENTIAL_LEN)
123131
}
124132
}
125133
}
@@ -135,11 +143,11 @@ impl Decodable for Asset {
135143
let explicit = Decodable::consensus_decode(&mut d)?;
136144
Ok(Self::Explicit(explicit))
137145
}
138-
p if p == 0x0a || p == 0x0b => {
139-
let mut comm = [0u8; 33];
146+
p if p == CONF_PREFIX_1 || p == CONF_PREFIX_2 => {
147+
let mut comm = [0u8; CONFIDENTIAL_LEN];
140148
comm[0] = p;
141149
d.read_exact(&mut comm[1..])?;
142-
Ok(Self::Confidential(Generator::from_slice(&comm[..])?))
150+
Ok(Self::Confidential(ConfInner::from_slice(&comm[..])?))
143151
}
144152
p => Err(encode::Error::InvalidConfidentialPrefix(p)),
145153
}
@@ -208,9 +216,9 @@ impl<'de> Deserialize<'de> for Asset {
208216

209217
/// Blinding factor used for asset commitments.
210218
#[derive(Copy, Clone, Eq, PartialEq, PartialOrd, Ord, Hash)]
211-
pub struct AssetBlindingFactor(pub(crate) Tweak);
219+
pub struct BlindingFactor(pub(crate) Tweak);
212220

213-
impl AssetBlindingFactor {
221+
impl BlindingFactor {
214222
/// Generate random asset blinding factor.
215223
pub fn new<R: Rng>(rng: &mut R) -> Self { Self(Tweak::new(rng)) }
216224

@@ -235,18 +243,18 @@ impl AssetBlindingFactor {
235243
pub fn zero() -> Self { Self(ZERO_TWEAK) }
236244
}
237245

238-
impl core::borrow::Borrow<[u8]> for AssetBlindingFactor {
246+
impl core::borrow::Borrow<[u8]> for BlindingFactor {
239247
fn borrow(&self) -> &[u8] { &self.0[..] }
240248
}
241249

242250
hex::impl_fmt_traits! {
243251
#[display_backward(true)]
244-
impl fmt_traits for AssetBlindingFactor {
252+
impl fmt_traits for BlindingFactor {
245253
const LENGTH: usize = 32;
246254
}
247255
}
248256

249-
impl str::FromStr for AssetBlindingFactor {
257+
impl str::FromStr for BlindingFactor {
250258
type Err = encode::Error;
251259

252260
fn from_str(s: &str) -> Result<Self, Self::Err> {
@@ -259,7 +267,7 @@ impl str::FromStr for AssetBlindingFactor {
259267
}
260268

261269
#[cfg(feature = "serde")]
262-
impl Serialize for AssetBlindingFactor {
270+
impl Serialize for BlindingFactor {
263271
fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
264272
if s.is_human_readable() {
265273
s.collect_str(&self)
@@ -270,13 +278,13 @@ impl Serialize for AssetBlindingFactor {
270278
}
271279

272280
#[cfg(feature = "serde")]
273-
impl<'de> Deserialize<'de> for AssetBlindingFactor {
281+
impl<'de> Deserialize<'de> for BlindingFactor {
274282
fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
275283
if d.is_human_readable() {
276284
struct HexVisitor;
277285

278286
impl ::serde::de::Visitor<'_> for HexVisitor {
279-
type Value = AssetBlindingFactor;
287+
type Value = BlindingFactor;
280288

281289
fn expecting(&self, formatter: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
282290
formatter.write_str("an ASCII hex string")
@@ -306,7 +314,7 @@ impl<'de> Deserialize<'de> for AssetBlindingFactor {
306314
struct BytesVisitor;
307315

308316
impl ::serde::de::Visitor<'_> for BytesVisitor {
309-
type Value = AssetBlindingFactor;
317+
type Value = BlindingFactor;
310318

311319
fn expecting(&self, formatter: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
312320
formatter.write_str("a bytestring")
@@ -321,7 +329,7 @@ impl<'de> Deserialize<'de> for AssetBlindingFactor {
321329
match <[u8; 32]>::try_from(v) {
322330
Ok(ret) => {
323331
let inner = Tweak::from_inner(ret).map_err(E::custom)?;
324-
Ok(AssetBlindingFactor(inner))
332+
Ok(BlindingFactor(inner))
325333
}
326334
Err(_) => Err(E::invalid_length(v.len(), &stringify!($len))),
327335
}

src/confidential/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,11 @@ use core::fmt;
2929

3030
use secp256k1_zkp;
3131

32-
pub use self::asset::{Asset, AssetBlindingFactor};
32+
pub use self::asset::{Asset, BlindingFactor as AssetBlindingFactor};
3333
pub use self::nonce::Nonce;
3434
pub use self::range_proof::RangeProof;
3535
pub use self::surjection_proof::SurjectionProof;
36-
pub use self::value::{Value, ValueBlindingFactor};
36+
pub use self::value::{BlindingFactor as ValueBlindingFactor, Value};
3737
use crate::encode;
3838
use crate::issuance::AssetId;
3939

src/confidential/nonce.rs

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,14 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer};
1313
use crate::encode::{self, Decodable, Encodable};
1414
use crate::hashes::sha256d;
1515

16+
type ExplicitInner = [u8; 32];
17+
type ConfInner = PublicKey;
18+
19+
const EXPLICIT_LEN: usize = 32;
20+
const CONFIDENTIAL_LEN: usize = 33;
21+
const CONF_PREFIX_1: u8 = 0x02;
22+
const CONF_PREFIX_2: u8 = 0x03;
23+
1624
/// A CT commitment to an output nonce (i.e. a public key)
1725
#[derive(Copy, Clone, Debug, Default, Eq, Hash, PartialEq, PartialOrd, Ord)]
1826
pub enum Nonce {
@@ -22,17 +30,17 @@ pub enum Nonce {
2230
/// There should be no such thing as an "explicit nonce", but Elements will deserialize
2331
/// such a thing (and insists that its size be 32 bytes). So we stick a 32-byte type here
2432
/// that implements all the traits we need.
25-
Explicit([u8; 32]),
33+
Explicit(ExplicitInner),
2634
/// Nonce is committed
27-
Confidential(PublicKey),
35+
Confidential(ConfInner),
2836
}
2937

3038
impl Nonce {
3139
/// Create nonce commitment.
3240
pub fn new_confidential<R: RngCore + CryptoRng, C: Signing>(
3341
rng: &mut R,
3442
secp: &Secp256k1<C>,
35-
receiver_blinding_pk: &PublicKey,
43+
receiver_blinding_pk: &ConfInner,
3644
) -> (Self, SecretKey) {
3745
let ephemeral_sk = SecretKey::new(rng);
3846
Self::with_ephemeral_sk(secp, ephemeral_sk, receiver_blinding_pk)
@@ -43,9 +51,9 @@ impl Nonce {
4351
pub fn with_ephemeral_sk<C: Signing>(
4452
secp: &Secp256k1<C>,
4553
ephemeral_sk: SecretKey,
46-
receiver_blinding_pk: &PublicKey,
54+
receiver_blinding_pk: &ConfInner,
4755
) -> (Self, SecretKey) {
48-
let sender_pk = PublicKey::from_secret_key(secp, &ephemeral_sk);
56+
let sender_pk = ConfInner::from_secret_key(secp, &ephemeral_sk);
4957
let shared_secret = Self::make_shared_secret(receiver_blinding_pk, &ephemeral_sk);
5058
(Self::Confidential(sender_pk), shared_secret)
5159
}
@@ -60,14 +68,14 @@ impl Nonce {
6068
}
6169

6270
/// Create the shared secret.
63-
fn make_shared_secret(pk: &PublicKey, sk: &SecretKey) -> SecretKey {
71+
fn make_shared_secret(pk: &ConfInner, sk: &SecretKey) -> SecretKey {
6472
let xy = secp256k1_zkp::ecdh::shared_secret_point(pk, sk);
6573
let shared_secret = {
6674
// Yes, what follows is the compressed representation of a Bitcoin public key.
6775
// However, this is more by accident then by design, see here: https://github.com/rust-bitcoin/rust-secp256k1/pull/255#issuecomment-744146282
6876

69-
let mut dh_secret = [0u8; 33];
70-
dh_secret[0] = if xy.last().unwrap() % 2 == 0 { 0x02 } else { 0x03 };
77+
let mut dh_secret = [0u8; CONFIDENTIAL_LEN];
78+
dh_secret[0] = if xy.last().unwrap() % 2 == 0 { CONF_PREFIX_1 } else { CONF_PREFIX_2 };
7179
dh_secret[1..].copy_from_slice(&xy[0..32]);
7280

7381
sha256d::Hash::hash(&dh_secret).to_byte_array()
@@ -80,15 +88,15 @@ impl Nonce {
8088
pub fn encoded_length(&self) -> usize {
8189
match *self {
8290
Self::Null => 1,
83-
Self::Explicit(..) => 33,
84-
Self::Confidential(..) => 33,
91+
Self::Explicit(..) => 1 + EXPLICIT_LEN,
92+
Self::Confidential(..) => CONFIDENTIAL_LEN,
8593
}
8694
}
8795

8896
/// Create from commitment.
8997
pub fn from_commitment(bytes: &[u8]) -> Result<Self, encode::Error> {
9098
Ok(Self::Confidential(
91-
PublicKey::from_slice(bytes).map_err(secp256k1_zkp::Error::Upstream)?,
99+
ConfInner::from_slice(bytes).map_err(secp256k1_zkp::Error::Upstream)?,
92100
))
93101
}
94102

@@ -103,7 +111,7 @@ impl Nonce {
103111

104112
/// Returns the explicit inner value.
105113
/// Returns [None] if [`Self::is_explicit`] returns false.
106-
pub fn explicit(&self) -> Option<[u8; 32]> {
114+
pub fn explicit(&self) -> Option<ExplicitInner> {
107115
match *self {
108116
Self::Explicit(i) => Some(i),
109117
_ => None,
@@ -112,16 +120,16 @@ impl Nonce {
112120

113121
/// Returns the confidential commitment in case of a confidential value.
114122
/// Returns [None] if [`Self::is_confidential`] returns false.
115-
pub fn commitment(&self) -> Option<PublicKey> {
123+
pub fn commitment(&self) -> Option<ConfInner> {
116124
match *self {
117125
Self::Confidential(i) => Some(i),
118126
_ => None,
119127
}
120128
}
121129
}
122130

123-
impl From<PublicKey> for Nonce {
124-
fn from(from: PublicKey) -> Self { Self::Confidential(from) }
131+
impl From<ConfInner> for Nonce {
132+
fn from(from: ConfInner) -> Self { Self::Confidential(from) }
125133
}
126134

127135
impl fmt::Display for Nonce {
@@ -149,7 +157,7 @@ impl Encodable for Nonce {
149157
}
150158
Self::Confidential(commitment) => {
151159
s.write_all(&commitment.serialize())?;
152-
Ok(33)
160+
Ok(CONFIDENTIAL_LEN)
153161
}
154162
}
155163
}
@@ -165,11 +173,11 @@ impl Decodable for Nonce {
165173
let explicit = Decodable::consensus_decode(&mut d)?;
166174
Ok(Self::Explicit(explicit))
167175
}
168-
p if p == 0x02 || p == 0x03 => {
169-
let mut comm = [0u8; 33];
176+
p if p == CONF_PREFIX_1 || p == CONF_PREFIX_2 => {
177+
let mut comm = [0u8; CONFIDENTIAL_LEN];
170178
comm[0] = p;
171179
d.read_exact(&mut comm[1..])?;
172-
Ok(Self::Confidential(PublicKey::from_slice(&comm)?))
180+
Ok(Self::Confidential(ConfInner::from_slice(&comm)?))
173181
}
174182
p => Err(encode::Error::InvalidConfidentialPrefix(p)),
175183
}

0 commit comments

Comments
 (0)