Skip to content

Commit cc1f0c3

Browse files
grumbachjoshuef
authored andcommittedSep 12, 2023
feat: unencrypted derivation index
BREAKING CHANGE: removes derivation index ciphers
1 parent cd88f3f commit cc1f0c3

File tree

6 files changed

+44
-80
lines changed

6 files changed

+44
-80
lines changed
 

‎src/README.md

+5-3
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,19 @@ A user has a main key - `MainKey` - which is a `bls::SecretKey`.
55
It is in essense a key _pair_, as the corresponding `bls::PublicKey` can be gotten from that secret key.
66
The `bls::PublicKey`of that key pair, is the `PublicAddress` to which anyone can send tokens.
77

8-
- A `Dbc` is a vehicle for transfering tokens.
8+
- A `Dbc` is a container that holds value (counted in tokens).
99

1010
- A `Dbc` has a unique identifier, `DbcId`, which is a `bls::PublicKey`.
1111
The corresponding `bls::SecretKey` called `DerivedKey`, unlocks the value.
1212

1313
- A `Dbc` can only be fully spent. So you unlock it and take out all the tokens, and the `Dbc` is spent.
1414

15+
- A `Dbc` cannot be made public as it contains secrets, what the Network only ever sees is `SignedSpend`, which tells us which `Dbc` was spent
16+
1517
### Sending tokens:
16-
When you send tokens to someone, you create a new `Dbc`, with a `DbcId` (a `bls::PublicKey`) by deriving it from the `PublicAddress` (a `bls::PublicKey`) of someone. You derive it using a random `DerivationIndex`, which you include (encrypted to the `PublicAddress`, which means only the corresponding `MainKey` can decrypt it) in the newly created `Dbc`.
18+
When you send tokens to someone, you create a new `Dbc`, with a `DbcId` (a `bls::PublicKey`) by deriving it from the `PublicAddress` (a `bls::PublicKey`) of someone. You derive it using a random `DerivationIndex`, which you include in the newly created `Dbc`.
1719
Also included in this new `Dbc` are the signatures of network nodes verifying that the input `Dbc(s)` that you emptied to create this new `Dbc`, are actually spent and was included in the transaction where this new `Dbc` was created. (The signatures part will change with the new network design.)
20+
Since `Dbc`s contain secrets, they should be encrypted before being sent.
1821

1922
### Unknown connection between Dbcs and PublicAddresses:
2023
Since the `DbcId` is derived from the `PublicAddress`, using a secret `DerivationIndex`, no one except sender and receiver knows that this new `Dbc` was sent to the `PublicAddress` of the receiver.
21-
The recipient decrypts the `DerivationIndex` cipher, using their `MainKey` (remember, it's the corresponding `bls::SecretKey` of the `bls::PublicKey` in the `PublicAddress`).

‎src/builder.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use crate::{
1010
transaction::{DbcTransaction, Output},
1111
DbcId, DerivationIndex, DerivedKey, FeeOutput, Input, PublicAddress, Spend,
1212
};
13-
use crate::{Dbc, DbcCiphers, Error, Hash, Result, SignedSpend, Token};
13+
use crate::{Dbc, DbcSecrets, Error, Hash, Result, SignedSpend, Token};
1414
#[cfg(feature = "serde")]
1515
use serde::{Deserialize, Serialize};
1616
use std::collections::{BTreeMap, BTreeSet};
@@ -237,7 +237,7 @@ impl DbcBuilder {
237237
Dbc {
238238
id: public_address.new_dbc_id(derivation_index),
239239
src_tx: self.spent_tx.clone(),
240-
ciphers: DbcCiphers::from((public_address, derivation_index)),
240+
secrets: DbcSecrets::from((public_address, derivation_index)),
241241
signed_spends: self.signed_spends.clone(),
242242
},
243243
output.token,

‎src/dbc.rs

+14-14
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
// permissions and limitations relating to use of the SAFE Network Software.
88

99
use crate::{
10-
dbc_id::PublicAddress, transaction::DbcTransaction, DbcCiphers, DbcId, DerivationIndex,
10+
dbc_id::PublicAddress, transaction::DbcTransaction, DbcId, DbcSecrets, DerivationIndex,
1111
DerivedKey, Error, FeeOutput, Hash, MainKey, Result, SignedSpend, Token,
1212
};
1313
#[cfg(feature = "serde")]
@@ -63,9 +63,9 @@ pub struct Dbc {
6363
/// The transaction where this DBC was created.
6464
#[debug(skip)]
6565
pub src_tx: DbcTransaction,
66-
/// Encrypted information for and about the recipient of this Dbc.
66+
/// Secret information for and about the recipient of this Dbc.
6767
#[debug(skip)]
68-
pub ciphers: DbcCiphers,
68+
pub secrets: DbcSecrets,
6969
/// The transaction's input's SignedSpends
7070
pub signed_spends: BTreeSet<SignedSpend>,
7171
}
@@ -78,7 +78,7 @@ impl Dbc {
7878

7979
// Return PublicAddress from which DbcId is derived.
8080
pub fn public_address(&self) -> &PublicAddress {
81-
&self.ciphers.public_address
81+
&self.secrets.public_address
8282
}
8383

8484
/// Return DerivedKey using MainKey supplied by caller.
@@ -88,12 +88,12 @@ impl Dbc {
8888
if &main_key.public_address() != self.public_address() {
8989
return Err(Error::MainKeyDoesNotMatchPublicAddress);
9090
}
91-
Ok(main_key.derive_key(&self.derivation_index(main_key)?))
91+
Ok(main_key.derive_key(&self.derivation_index()))
9292
}
9393

9494
/// Return the derivation index that was used to derive DbcId and corresponding DerivedKey of a Dbc.
95-
pub fn derivation_index(&self, main_key: &MainKey) -> Result<DerivationIndex> {
96-
self.ciphers.derivation_index(main_key)
95+
pub fn derivation_index(&self) -> DerivationIndex {
96+
self.secrets.derivation_index
9797
}
9898

9999
/// Return the fee output used in the source transaction
@@ -126,7 +126,7 @@ impl Dbc {
126126
pub fn hash(&self) -> Hash {
127127
let mut sha3 = Sha3::v256();
128128
sha3.update(self.src_tx.hash().as_ref());
129-
sha3.update(&self.ciphers.to_bytes());
129+
sha3.update(&self.secrets.to_bytes());
130130

131131
for sp in self.signed_spends.iter() {
132132
sha3.update(&sp.to_bytes());
@@ -216,11 +216,11 @@ pub(crate) mod tests {
216216
outputs: vec![Output::new(derived_key.dbc_id(), amount)],
217217
fee: FeeOutput::new(Hash::default(), 3_500, Hash::default()),
218218
};
219-
let ciphers = DbcCiphers::from((&main_key.public_address(), &derivation_index));
219+
let ciphers = DbcSecrets::from((&main_key.public_address(), &derivation_index));
220220
let dbc = Dbc {
221221
id: derived_key.dbc_id(),
222222
src_tx: tx,
223-
ciphers,
223+
secrets: ciphers,
224224
signed_spends: Default::default(),
225225
};
226226

@@ -247,11 +247,11 @@ pub(crate) mod tests {
247247
outputs: vec![Output::new(derived_key.dbc_id(), amount)],
248248
fee: FeeOutput::new(Hash::default(), 2_500, Hash::default()),
249249
};
250-
let ciphers = DbcCiphers::from((&main_key.public_address(), &derivation_index));
250+
let ciphers = DbcSecrets::from((&main_key.public_address(), &derivation_index));
251251
let dbc = Dbc {
252252
id: derived_key.dbc_id(),
253253
src_tx: tx,
254-
ciphers,
254+
secrets: ciphers,
255255
signed_spends: Default::default(),
256256
};
257257

@@ -303,11 +303,11 @@ pub(crate) mod tests {
303303
fee: FeeOutput::default(),
304304
};
305305

306-
let ciphers = DbcCiphers::from((&main_key.public_address(), &derivation_index));
306+
let ciphers = DbcSecrets::from((&main_key.public_address(), &derivation_index));
307307
let dbc = Dbc {
308308
id: derived_key.dbc_id(),
309309
src_tx: tx,
310-
ciphers,
310+
secrets: ciphers,
311311
signed_spends: Default::default(),
312312
};
313313

‎src/dbc_ciphers.rs

+16-29
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,14 @@
66
// KIND, either express or implied. Please review the Licences for the specific language governing
77
// permissions and limitations relating to use of the SAFE Network Software.
88

9-
use crate::{dbc_id::PublicAddress, DerivationIndex, Hash, MainKey, Result};
10-
use blsttc::Ciphertext;
9+
use crate::{dbc_id::PublicAddress, DerivationIndex, Hash};
1110
#[cfg(feature = "serde")]
1211
use serde::{Deserialize, Serialize};
1312
use tiny_keccak::{Hasher, Sha3};
1413

1514
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1615
#[derive(Debug, PartialEq, Eq, Clone)]
17-
pub struct DbcCiphers {
16+
pub struct DbcSecrets {
1817
/// This is the PublicAddress to which tokens are send. The PublicAddress may be published
1918
/// and multiple payments sent to this address by various parties. It is useful for
2019
/// accepting donations, for example.
@@ -26,56 +25,44 @@ pub struct DbcCiphers {
2625
/// and never seen by the spentbook nodes.
2726
///
2827
/// The DbcId used in the transaction is derived from this PublicAddress using a random
29-
/// derivation index, which is stored (encrypted) in derivation_index_cipher.
28+
/// derivation index, which is stored in derivation_index.
3029
pub public_address: PublicAddress,
3130

3231
/// This indicates which index to use when deriving the DbcId of the
3332
/// Dbc, from the PublicAddress.
34-
///
35-
/// This index is stored in encrypted form, and is encrypted to the PublicAddress.
36-
/// So the actual PublicAddress the tokens in this Dbc was sent to, is unknown to
37-
/// anyone not in posession of the MainKey corresponding to the above mentioned PublicAddress.
38-
pub derivation_index_cipher: Ciphertext,
33+
pub derivation_index: DerivationIndex,
3934
}
4035

41-
/// Represents the ciphers of a Dbc.
42-
impl From<(PublicAddress, Ciphertext)> for DbcCiphers {
43-
// Create a new DbcCiphers for signing.
44-
fn from(params: (PublicAddress, Ciphertext)) -> Self {
45-
let (public_address, derivation_index_cipher) = params;
36+
/// Represents the Secrets of a Dbc.
37+
impl From<(PublicAddress, DerivationIndex)> for DbcSecrets {
38+
// Create a new DbcSecrets for signing.
39+
fn from(params: (PublicAddress, DerivationIndex)) -> Self {
40+
let (public_address, derivation_index) = params;
4641
Self {
4742
public_address,
48-
derivation_index_cipher,
43+
derivation_index,
4944
}
5045
}
5146
}
5247

53-
/// Represents the ciphers of a Dbc.
54-
impl From<(&PublicAddress, &DerivationIndex)> for DbcCiphers {
55-
// Create a new DbcCiphers for signing.
48+
/// Represents the Secrets of a Dbc.
49+
impl From<(&PublicAddress, &DerivationIndex)> for DbcSecrets {
50+
// Create a new DbcSecrets for signing.
5651
fn from(params: (&PublicAddress, &DerivationIndex)) -> Self {
5752
let (public_address, derivation_index) = params;
58-
let derivation_index_cipher = public_address.encrypt(derivation_index);
5953

6054
Self {
6155
public_address: *public_address,
62-
derivation_index_cipher,
56+
derivation_index: *derivation_index,
6357
}
6458
}
6559
}
6660

67-
impl DbcCiphers {
68-
pub(crate) fn derivation_index(&self, key_source: &MainKey) -> Result<DerivationIndex> {
69-
let bytes = key_source.decrypt_index(&self.derivation_index_cipher)?;
70-
let mut idx = [0u8; 32];
71-
idx.copy_from_slice(&bytes[0..32]);
72-
Ok(idx)
73-
}
74-
61+
impl DbcSecrets {
7562
pub fn to_bytes(&self) -> Vec<u8> {
7663
let mut bytes: Vec<u8> = Default::default();
7764
bytes.extend(&self.public_address.to_bytes());
78-
bytes.extend(&self.derivation_index_cipher.to_bytes());
65+
bytes.extend(&self.derivation_index);
7966
bytes
8067
}
8168

‎src/dbc_id.rs

+6-31
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@
88

99
use crate::{
1010
rand::{distributions::Standard, Rng, RngCore},
11-
Error, PublicKey, Result,
11+
PublicKey,
1212
};
13-
use blsttc::{serde_impl::SerdeSecret, Ciphertext, SecretKey, PK_SIZE};
13+
use blsttc::{serde_impl::SerdeSecret, SecretKey, PK_SIZE};
1414
#[cfg(feature = "serde")]
1515
use serde::{Deserialize, Serialize};
1616

@@ -70,7 +70,7 @@ impl DerivedKey {
7070
/// they generate the id of the Dbc - the DbcId - that shall hold the tokens.
7171
/// The DbcId is generated from this PublicAddress, and only the sender
7272
/// will at this point know that the DbcId is related to this PublicAddress.
73-
/// When creating the Dbc using that DbcId, the sender will also encrypt the
73+
/// When creating the Dbc using that DbcId, the sender will also include the
7474
/// DerivationIndex that was used to generate the DbcId, so that the recipient behind
7575
/// the PublicAddress can also see that the DbcId is related to this PublicAddress.
7676
/// The recipient can then use the received DerivationIndex to generate the DerivedKey
@@ -97,11 +97,6 @@ impl PublicAddress {
9797
DbcId(self.0.derive_child(index))
9898
}
9999

100-
/// To send tokens to this address, a derivation index is encrypted
101-
pub fn encrypt(&self, derivation_index: &DerivationIndex) -> Ciphertext {
102-
self.0.encrypt(derivation_index)
103-
}
104-
105100
pub fn to_bytes(self) -> [u8; PK_SIZE] {
106101
self.0.to_bytes()
107102
}
@@ -133,37 +128,17 @@ impl MainKey {
133128
self.0.sign(msg)
134129
}
135130

136-
/// When someone wants to send tokens to the PublicAddress of this MainKey,
137-
/// they generate the id of the Dbc - the DbcId - that shall hold the tokens.
138-
/// The created Dbc contains the encrypted derivation index, that is decrypted using
139-
/// this MainKey instance.
140-
/// The index is then used to derive the key - the DerivedKey - corresponding to the DbcId of the
141-
/// Dbc sent to you. With that DerivedKey you will have access to the tokens in the Dbc.
142-
pub fn decrypt_index(&self, derivation_index_cipher: &Ciphertext) -> Result<DerivationIndex> {
143-
let bytes = self
144-
.0
145-
.decrypt(derivation_index_cipher)
146-
.ok_or(Error::DecryptionBySecretKeyFailed)?;
147-
148-
let mut index = [0u8; 32];
149-
index.copy_from_slice(&bytes[0..32]);
150-
151-
Ok(index)
152-
}
153-
154131
/// Derive the key - the DerivedKey - corresponding to a DbcId
155132
/// which was also derived using the same DerivationIndex.
156133
///
157134
/// When someone wants to send tokens to the PublicAddress of this MainKey,
158135
/// they generate the id of the Dbc - the DbcId - that shall hold the tokens.
159136
/// The recipient of the tokens, is the person/entity that holds this MainKey.
160137
///
161-
/// The created Dbc contains the _encrypted_ form of the derivation index that was used to
162-
/// generate that very DbcId. The sender encrypted it so that no-one but the recipient of the
163-
/// tokens in the Dbc (and the sender itself of course) shall be able to see which index was used.
164-
/// This encrypted index is then decrypted by the recipient, using this MainKey instance (see `fn decrypt_index` above).
138+
/// The created Dbc contains the derivation index that was used to
139+
/// generate that very DbcId.
165140
///
166-
/// When passing the resulting decrypted derivation index to this function (`fn derive_key`),
141+
/// When passing the derivation index to this function (`fn derive_key`),
167142
/// a DerivedKey is generated corresponding to the DbcId. This DerivedKey can unlock the Dbc of that
168143
/// DbcId, thus giving access to the tokens it holds.
169144
/// By that, the recipient has received the tokens from the sender.

‎src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ pub mod mock;
2525
pub use crate::{
2626
builder::{DbcBuilder, TransactionBuilder},
2727
dbc::Dbc,
28-
dbc_ciphers::DbcCiphers,
28+
dbc_ciphers::DbcSecrets,
2929
dbc_id::{random_derivation_index, DbcId, DerivationIndex, DerivedKey, MainKey, PublicAddress},
3030
error::{Error, Result},
3131
fee_output::FeeOutput,

0 commit comments

Comments
 (0)
Please sign in to comment.