Skip to content

Commit

Permalink
Add stct proof support
Browse files Browse the repository at this point in the history
  • Loading branch information
Daksh14 committed Oct 31, 2023
1 parent 3bbb25b commit 4984143
Show file tree
Hide file tree
Showing 4 changed files with 233 additions and 36 deletions.
Binary file removed assets/dusk_wallet_core.wasm
Binary file not shown.
89 changes: 88 additions & 1 deletion assets/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -798,7 +798,7 @@
}
}
},
"getStctProof": {
"GetStctProofArgs": {
"description": "Get the bytes for the stct proof to send to the node",
"type": "object",
"required": ["rng_seed", "seed", "refund", "value", "sender_index", "gas_limit", "gas_price"],
Expand Down Expand Up @@ -840,6 +840,93 @@
"type": "integer"
}
}
},
"GetStctProofResponse": {
"description": "Response of the get_stct_proof function",
"type": "object",
"required": ["bytes", "signature"],
"properties": {
"bytes": {
"description": "The bytes of the stct proof to send to the node",
"type": "array",
"items": {
"type": "integer",
"format": "uint8"
}
},
"signature": {
"description": "The signature of the stct proof",
"type": "array",
"items": {
"type": "integer",
"format": "uint8"
}
}
}
},
"GetStakeCallDataArgs": {
"description": "Get the call data for stakeing",
"type": "object",
"required": ["staker_index", "seed", "spend_proof", "value", "signature"],
"properties": {
"staker_index": {
"description": "Index of the address of the staker in the seed",
"type": "integer",
"format": "uint8"
},
"seed": {
"description": "The seed to generate the sender keys from",
"type": "array",
"items": {
"type": "integer",
"format": "uint8"
}
},
"spend_proof": {
"description": "The stct proof as recieved from the node",
"type": "array",
"items": {
"type": "integer",
"format": "uint8"
}
},
"value": {
"description": "The amount of value to stake",
"type": "integer",
"format": "uint64"
},
"signature": {
"description": "The signature of the stct proof",
"type": "array",
"items": {
"type": "integer",
"format": "uint8"
}
}
}
},
"GetStakeCallDataResponse": {
"description": "Response of the get_stake_call_data function, send this to the call_data in execute",
"type": "object",
"required": ["contract", "method", "payload"],
"properties": {
"contract": {
"description": "The contract to call encoded in bs58 format",
"type": "string"
},
"method": {
"description": "The method to call on the contract",
"type": "string"
},
"payload": {
"description": "The payload of the call",
"type": "array",
"items": {
"type": "integer",
"format": "uint8"
}
}
}
}
}
}
130 changes: 95 additions & 35 deletions src/compat/crypto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,22 @@
//
// Copyright (c) DUSK NETWORK. All rights reserved.

use dusk_bls12_381_sign::PublicKey;
use dusk_bytes::Serializable;
use dusk_jubjub::{BlsScalar, JubJubScalar, JubJubAffine};
use phoenix_core::{Note, Crossover, Fee, transaction::*};
use dusk_schnorr::{ Signature};
use dusk_pki::{Ownable, SecretKey as SchnorrKey};
use dusk_bytes::Write;
use dusk_jubjub::{BlsScalar, JubJubAffine, JubJubScalar};
use dusk_pki::{Ownable, SecretKey as SchnorrKey};
use dusk_schnorr::Signature;
use phoenix_core::{transaction::*, Crossover, Fee, Note};

use alloc::vec::Vec;

use crate::{key::{self, derive_ssk}, types, utils, MAX_KEY, MAX_LEN};
use crate::{
key::{self, derive_sk, derive_ssk},
types::{self},
utils::{self, bs58_to_psk},
MAX_KEY, MAX_LEN,
};

const STCT_INPUT_SIZE: usize = Fee::SIZE
+ Crossover::SIZE
Expand Down Expand Up @@ -143,9 +149,17 @@ pub fn unspent_spent_notes(args: i32, len: i32) -> i64 {

#[no_mangle]
pub fn get_stct_proof(args: i32, len: i32) -> i64 {
let type::CrossoverFeeArgs { rng_seed, seed, refund, value, sender_index, gas_limit, gas_price } = match utils::take_args(args, len) {
let types::GetStctProofArgs {
rng_seed,
seed,
refund,
value,
sender_index,
gas_limit,
gas_price,
} = match utils::take_args(args, len) {
Some(a) => a,
None => return utils::fail()
None => return utils::fail(),
};

let rng_seed = match utils::sanitize_seed(rng_seed) {
Expand All @@ -158,38 +172,40 @@ pub fn get_stct_proof(args: i32, len: i32) -> i64 {
None => return utils::fail(),
};


let sender = derive_ssk(&seed, sender_index);
let refund = match bs58_to_psk(&refund) {
Some(a) => a,
None => return utils::fail(),
};

let rng = &mut utils::rng(&rng_seed);

let blinder = JubJubScalar::random(rng);
let note = Note::obfuscated(rng, refund, value, blinder);
let (mut fee, crossover) = note
.try_into()
.expect("Obfuscated notes should always yield crossovers");
let note = Note::obfuscated(rng, &refund, value, blinder);
let (mut fee, crossover) = note
.try_into()
.expect("Obfuscated notes should always yield crossovers");

let contract_id = rusk_abi::STAKE_CONTRACT;
let address = rusk_abi::contract_to_scalar(&contract_id);
let contract_id = rusk_abi::STAKE_CONTRACT;
let address = rusk_abi::contract_to_scalar(&contract_id);

let contract_id = rusk_abi::contract_to_scalar(&contract_id);
let contract_id = rusk_abi::contract_to_scalar(&contract_id);

let stct_message =
stct_signature_message(&crossover, value, contract_id);
let stct_message = dusk_poseidon::sponge::hash(&stct_message);
let stct_message = stct_signature_message(&crossover, value, contract_id);
let stct_message = dusk_poseidon::sponge::hash(&stct_message);

let sk_r = *sender.sk_r(fee.stealth_address()).as_ref();
let secret = SchnorrKey::from(sk_r);
let sk_r = *sender.sk_r(fee.stealth_address()).as_ref();
let secret = SchnorrKey::from(sk_r);

fee.gas_limit = gas_limit;
fee.gas_price = gas_price;
fee.gas_limit = gas_limit;
fee.gas_price = gas_price;

let stct_signature = Signature::new(&secret, rng, stct_message);
let stct_signature = Signature::new(&secret, rng, stct_message);

fn get_buf(fee: Fee, crossover: Crossover, value: u64, blinder: JubJubScalar, address: BlsScalar, stct_signature: Signature) -> Option<[u8; STCT_INPUT_SIZE]> {
let mut buf = [0; STCT_INPUT_SIZE];
let mut writer = &mut buf[..];
let mut buf = [0; STCT_INPUT_SIZE];
let mut writer = &mut buf[..];

let mut bytes = || {
writer.write(&fee.to_bytes()).ok()?;
writer.write(&crossover.to_bytes()).ok()?;
writer.write(&value.to_bytes()).ok()?;
Expand All @@ -198,15 +214,59 @@ pub fn get_stct_proof(args: i32, len: i32) -> i64 {
writer.write(&stct_signature.to_bytes()).ok()?;

Some(buf)
}
};

let buf = match get_buf(fee, crossover, value, blinder, address, stct_signature) {
Some(a) => a,
None => return utils::fail(),
};
let bytes = match bytes() {
Some(a) => a,
None => return utils::fail(),
}
.to_vec();

let signature = match rkyv::to_bytes(&stct_signature) {
Ok(a) => a.to_vec(),
Err(_) => return utils::fail(),
};

utils::into_ptr(types::CrossoverFeeArgsResponse {
buffer: buf
})
utils::into_ptr(types::GetStctProofResponse { bytes, signature })
}

pub fn get_stake_call_data(args: i32, len: i32) -> i64 {
let types::GetStakeCallDataArgs {
staker_index,
seed,
spend_proof,
value,
signature,
} = match utils::take_args(args, len) {
Some(a) => a,
None => return utils::fail(),
};

}
let seed = match utils::sanitize_seed(seed) {
Some(s) => s,
None => return utils::fail(),
};

let sk = derive_sk(&seed, staker_index);
let pk = PublicKey::from(&sk);

let stake = Stake {
public_key: pk,
signature,
value,
proof: spend_proof,
};

let contract = bs58::encode(rusk_abi::STAKE_CONTRACT).into_string();
let method = "stake";
let payload = match rkyv::to_bytes::<_, MAX_LEN>(&stake).ok() {
Some(a) => a.to_vec(),
None => return utils::fail(),
};

utils::into_ptr(types::GetStakeCallDataResponse {
contract,
method,
payload,
})
}
50 changes: 50 additions & 0 deletions src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,56 @@ pub struct GetMnemonicSeedResponse {
#[doc = " Seed bytes from the given passphrase and Mnemonic"]
pub mnemonic_seed: Vec<u8>,
}
#[doc = " Get the call data for stakeing"]
#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
pub struct GetStakeCallDataArgs {
#[doc = " The seed to generate the sender keys from"]
pub seed: Vec<u8>,
#[doc = " The signature of the stct proof"]
pub signature: Vec<u8>,
#[doc = " The stct proof as recieved from the node"]
pub spend_proof: Vec<u8>,
#[doc = " Index of the address of the staker in the seed"]
pub staker_index: u64,
#[doc = " The amount of value to stake"]
pub value: u64,
}
#[doc = " Response of the get_stake_call_data function, send this to the call_data in execute"]
#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
pub struct GetStakeCallDataResponse {
#[doc = " The contract to call encoded in bs58 format"]
pub contract: String,
#[doc = " The method to call on the contract"]
pub method: String,
#[doc = " The payload of the call"]
pub payload: Vec<u8>,
}
#[doc = " Get the bytes for the stct proof to send to the node"]
#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
pub struct GetStctProofArgs {
#[doc = " The gas limit of the transaction"]
pub gas_limit: u64,
#[doc = " The gas price of the transaction"]
pub gas_price: u64,
#[doc = " The refund address in base58 format"]
pub refund: String,
#[doc = " The rng seed to generate the entropy for the notes"]
pub rng_seed: Vec<u8>,
#[doc = " The seed to generate the sender keys from"]
pub seed: Vec<u8>,
#[doc = " index of the sender in the seed"]
pub sender_index: u64,
#[doc = " The amount of value to send"]
pub value: u64,
}
#[doc = " Response of the get_stct_proof function"]
#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
pub struct GetStctProofResponse {
#[doc = " The bytes of the stct proof to send to the node"]
pub bytes: Vec<u8>,
#[doc = " The signature of the stct proof"]
pub signature: Vec<u8>,
}
#[doc = " The arguments of the merge_notes function"]
#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
pub struct MergeNotesArgs {
Expand Down

0 comments on commit 4984143

Please sign in to comment.