feat: key management added

This commit is contained in:
Oleksandr Pravdyvyi 2024-10-25 09:41:43 +03:00
parent 76ba2640c0
commit 480dbc4f07
5 changed files with 409 additions and 3 deletions

193
Cargo.lock generated
View File

@ -7,10 +7,15 @@ name = "accounts"
version = "0.1.0"
dependencies = [
"anyhow",
"elliptic-curve",
"env_logger",
"k256",
"log",
"rand 0.8.5",
"serde",
"serde_json",
"sha2 0.10.8",
"storage",
]
[[package]]
@ -329,12 +334,24 @@ dependencies = [
"windows-targets",
]
[[package]]
name = "base16ct"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf"
[[package]]
name = "base64"
version = "0.22.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
[[package]]
name = "base64ct"
version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b"
[[package]]
name = "bindgen"
version = "0.65.1"
@ -517,6 +534,12 @@ dependencies = [
"tokio",
]
[[package]]
name = "const-oid"
version = "0.9.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8"
[[package]]
name = "constant_time_eq"
version = "0.1.5"
@ -553,6 +576,18 @@ version = "0.8.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80"
[[package]]
name = "crypto-bigint"
version = "0.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76"
dependencies = [
"generic-array 0.14.7",
"rand_core 0.6.4",
"subtle 2.6.1",
"zeroize",
]
[[package]]
name = "crypto-common"
version = "0.1.6"
@ -570,7 +605,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5"
dependencies = [
"generic-array 0.12.4",
"subtle",
"subtle 1.0.0",
]
[[package]]
name = "der"
version = "0.7.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0"
dependencies = [
"const-oid",
"zeroize",
]
[[package]]
@ -611,7 +656,42 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
dependencies = [
"block-buffer 0.10.4",
"const-oid",
"crypto-common",
"subtle 2.6.1",
]
[[package]]
name = "ecdsa"
version = "0.16.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca"
dependencies = [
"der",
"digest 0.10.7",
"elliptic-curve",
"rfc6979",
"signature",
"spki",
]
[[package]]
name = "elliptic-curve"
version = "0.13.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47"
dependencies = [
"base16ct",
"crypto-bigint",
"digest 0.10.7",
"ff",
"generic-array 0.14.7",
"group",
"pkcs8",
"rand_core 0.6.4",
"sec1",
"subtle 2.6.1",
"zeroize",
]
[[package]]
@ -648,6 +728,16 @@ version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
[[package]]
name = "ff"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449"
dependencies = [
"rand_core 0.6.4",
"subtle 2.6.1",
]
[[package]]
name = "fnv"
version = "1.0.7"
@ -769,6 +859,7 @@ checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
dependencies = [
"typenum",
"version_check",
"zeroize",
]
[[package]]
@ -805,6 +896,17 @@ version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
[[package]]
name = "group"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63"
dependencies = [
"ff",
"rand_core 0.6.4",
"subtle 2.6.1",
]
[[package]]
name = "h2"
version = "0.3.26"
@ -867,6 +969,15 @@ version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
[[package]]
name = "hmac"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e"
dependencies = [
"digest 0.10.7",
]
[[package]]
name = "http"
version = "0.2.12"
@ -942,6 +1053,20 @@ dependencies = [
"libc",
]
[[package]]
name = "k256"
version = "0.13.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f6e3919bbaa2945715f0bb6d3934a173d1e9a59ac23767fbaaef277265a7411b"
dependencies = [
"cfg-if 1.0.0",
"ecdsa",
"elliptic-curve",
"once_cell",
"sha2 0.10.8",
"signature",
]
[[package]]
name = "keccak"
version = "0.1.5"
@ -1387,6 +1512,16 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
[[package]]
name = "pkcs8"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7"
dependencies = [
"der",
"spki",
]
[[package]]
name = "pkg-config"
version = "0.3.31"
@ -1563,6 +1698,16 @@ version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
[[package]]
name = "rfc6979"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2"
dependencies = [
"hmac",
"subtle 2.6.1",
]
[[package]]
name = "rocksdb"
version = "0.21.0"
@ -1626,6 +1771,20 @@ version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "sec1"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc"
dependencies = [
"base16ct",
"der",
"generic-array 0.14.7",
"pkcs8",
"subtle 2.6.1",
"zeroize",
]
[[package]]
name = "semver"
version = "1.0.23"
@ -1791,6 +1950,16 @@ dependencies = [
"libc",
]
[[package]]
name = "signature"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de"
dependencies = [
"digest 0.10.7",
"rand_core 0.6.4",
]
[[package]]
name = "slab"
version = "0.4.9"
@ -1826,6 +1995,16 @@ dependencies = [
"windows-sys 0.52.0",
]
[[package]]
name = "spki"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d"
dependencies = [
"base64ct",
"der",
]
[[package]]
name = "storage"
version = "0.1.0"
@ -1849,6 +2028,12 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee"
[[package]]
name = "subtle"
version = "2.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
[[package]]
name = "syn"
version = "2.0.79"
@ -2206,6 +2391,12 @@ dependencies = [
"syn",
]
[[package]]
name = "zeroize"
version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde"
[[package]]
name = "zkvm"
version = "0.1.0"

View File

@ -40,6 +40,18 @@ rocksdb = { version = "0.21.0", default-features = false, features = ["snappy"]
#ToDo: Add necessary risc0 submodules for zkvm module
[workspace.dependencies.rand]
features = ["std", "std_rng", "getrandom"]
version = "0.8.5"
[workspace.dependencies.k256]
features = ["ecdsa-core", "arithmetic", "expose-field"]
version = "0.13.4"
[workspace.dependencies.elliptic-curve]
features = ["arithmetic"]
version = "0.13.8"
[workspace.dependencies.serde]
features = ["derive"]
version = "1.0.60"

View File

@ -8,4 +8,11 @@ anyhow.workspace = true
serde_json.workspace = true
env_logger.workspace = true
log.workspace = true
serde.workspace = true
serde.workspace = true
k256.workspace = true
sha2.workspace = true
rand.workspace = true
elliptic-curve.workspace = true
[dependencies.storage]
path = "../storage"

View File

@ -0,0 +1,196 @@
use k256::elliptic_curve::group::GroupEncoding;
use k256::{elliptic_curve::PrimeField, AffinePoint, FieldBytes, Scalar};
use rand::{rngs::OsRng, RngCore};
use sha2::{digest::FixedOutput, Digest};
use storage::merkle_tree_public::TreeHashType;
pub const NULLIFIER_SECRET_CONST: [u8; 32] = [
38, 29, 97, 210, 148, 172, 75, 220, 36, 249, 27, 111, 73, 14, 250, 38, 55, 87, 164, 169, 95,
101, 135, 28, 212, 241, 107, 46, 162, 60, 59, 93,
];
pub const VIEVING_SECRET_CONST: [u8; 32] = [
97, 23, 175, 117, 11, 48, 215, 162, 150, 103, 46, 195, 179, 178, 93, 52, 137, 190, 202, 60,
254, 87, 112, 250, 57, 242, 117, 206, 195, 149, 213, 206,
];
#[derive(Debug)]
///Seed holder. Non-clonable to ensure that different holders use different seeds.
/// Produces `TopSecretKeyHolder` objects.
pub struct SeedHolder {
seed: Scalar,
}
#[derive(Debug, Clone)]
///Secret spending key holder. Produces `UTXOSecretKeyHolder` objects.
pub struct TopSecretKeyHolder {
secret_spending_key: Scalar,
}
#[derive(Debug, Clone)]
///Nullifier secret key and viewing secret key holder. Produces public keys. Can produce address. Can produce shared secret for recepient.
pub struct UTXOSecretKeyHolder {
nullifier_secret_key: Scalar,
viewing_secret_key: Scalar,
}
impl SeedHolder {
pub fn new_os_random() -> Self {
let mut bytes = FieldBytes::default();
OsRng.fill_bytes(&mut bytes);
Self {
seed: Scalar::from_repr(bytes).unwrap(),
}
}
pub fn generate_secret_spending_key_hash(&self) -> TreeHashType {
let mut hasher = sha2::Sha256::new();
hasher.update(self.seed.to_bytes());
<TreeHashType>::from(hasher.finalize_fixed())
}
pub fn generate_secret_spending_key_scalar(&self) -> Scalar {
let hash = self.generate_secret_spending_key_hash();
Scalar::from_repr(hash.into()).unwrap()
}
pub fn produce_top_secret_key_holder(&self) -> TopSecretKeyHolder {
TopSecretKeyHolder {
secret_spending_key: self.generate_secret_spending_key_scalar(),
}
}
}
impl TopSecretKeyHolder {
pub fn generate_nullifier_secret_key(&self) -> Scalar {
let mut hasher = sha2::Sha256::new();
hasher.update(self.secret_spending_key.to_bytes());
hasher.update(NULLIFIER_SECRET_CONST);
let hash = <TreeHashType>::from(hasher.finalize_fixed());
Scalar::from_repr(hash.into()).unwrap()
}
pub fn generate_viewing_secret_key(&self) -> Scalar {
let mut hasher = sha2::Sha256::new();
hasher.update(self.secret_spending_key.to_bytes());
hasher.update(VIEVING_SECRET_CONST);
let hash = <TreeHashType>::from(hasher.finalize_fixed());
Scalar::from_repr(hash.into()).unwrap()
}
pub fn produce_utxo_secret_holder(&self) -> UTXOSecretKeyHolder {
UTXOSecretKeyHolder {
nullifier_secret_key: self.generate_nullifier_secret_key(),
viewing_secret_key: self.generate_viewing_secret_key(),
}
}
}
impl UTXOSecretKeyHolder {
pub fn generate_nullifier_public_key(&self) -> AffinePoint {
(AffinePoint::GENERATOR * self.nullifier_secret_key).into()
}
pub fn generate_viewing_public_key(&self) -> AffinePoint {
(AffinePoint::GENERATOR * self.viewing_secret_key).into()
}
pub fn generate_address(&self) -> TreeHashType {
let npk = self.generate_nullifier_public_key();
let vpk = self.generate_viewing_public_key();
let mut hasher = sha2::Sha256::new();
hasher.update(npk.to_bytes());
hasher.update(vpk.to_bytes());
<TreeHashType>::from(hasher.finalize_fixed())
}
}
#[derive(Debug)]
///Ephemeral secret key holder. Non-clonable as intended for one-time use. Produces ephemeral public keys. Can produce shared secret for sender.
pub struct EphemeralKeyHolder {
ephemeral_secret_key: Scalar,
}
impl EphemeralKeyHolder {
pub fn new_os_random() -> Self {
let mut bytes = FieldBytes::default();
OsRng.fill_bytes(&mut bytes);
Self {
ephemeral_secret_key: Scalar::from_repr(bytes).unwrap(),
}
}
pub fn generate_ephemeral_public_key(&self) -> AffinePoint {
(AffinePoint::GENERATOR * self.ephemeral_secret_key).into()
}
pub fn calculate_shared_secret_sender(
&self,
viewing_public_key_receiver: AffinePoint,
) -> AffinePoint {
(viewing_public_key_receiver * self.ephemeral_secret_key).into()
}
pub fn encrypt_data(&self) {
//ToDo: Implement that
//Need clarification on exact symmetric encoding, which we want to use for ECIES
todo!()
}
}
#[derive(Debug)]
///Entrypoint to key management
pub struct AddressKeyHolder {
utxo_secret_key_holder: UTXOSecretKeyHolder,
pub address: TreeHashType,
pub nullifer_public_key: AffinePoint,
pub viewing_public_key: AffinePoint,
}
impl AddressKeyHolder {
pub fn new_os_random() -> Self {
//Currently dropping SeedHolder and TopSecretKeyHolder at the end of initialization.
//Now entirely sure if we need them in the future.
let seed_holder = SeedHolder::new_os_random();
let top_secret_key_holder = seed_holder.produce_top_secret_key_holder();
let utxo_secret_key_holder = top_secret_key_holder.produce_utxo_secret_holder();
let address = utxo_secret_key_holder.generate_address();
let nullifer_public_key = utxo_secret_key_holder.generate_nullifier_public_key();
let viewing_public_key = utxo_secret_key_holder.generate_viewing_public_key();
Self {
utxo_secret_key_holder,
address,
nullifer_public_key,
viewing_public_key,
}
}
pub fn calculate_shared_secret_receiver(
&self,
ephemeral_public_key_sender: AffinePoint,
) -> AffinePoint {
(ephemeral_public_key_sender * self.utxo_secret_key_holder.viewing_secret_key).into()
}
pub fn produce_ephemeral_key_holder(&self) -> EphemeralKeyHolder {
EphemeralKeyHolder::new_os_random()
}
}

View File

@ -1 +1 @@
//ToDo: Add accounts module
pub mod key_management;