Giter Site home page Giter Site logo

layerxcom / zero-chain Goto Github PK

View Code? Open in Web Editor NEW
261.0 29.0 47.0 539.88 MB

A privacy-preserving blockchain on Substrate

Home Page: https://layerxcom.github.io/zerochain-book/

License: GNU General Public License v3.0

Rust 99.72% Shell 0.17% Dockerfile 0.11%
substrate zero-knowledge blockchain rust zk-snarks

zero-chain's Issues

Fix something wrong with the pairing test for a swap of the endian

{
let mut rdecoded_le = R::default();
let mut rdecoded_be_flip = R::default();
let mut v: Vec<u8> = vec![];
r.write_le(&mut &mut v).unwrap();
// This reads in little-endian, so we are done.
rdecoded_le.read_le(&mut &v[..]).unwrap();
// This reads in big-endian, so we perform a swap of the
// bytes beforehand.
let v: Vec<u8> = v.into_iter().rev().collect();
rdecoded_be_flip.read_be(&mut &v[..]).unwrap();
assert_eq!(rdecoded_le, rdecoded_be_flip);
}

got the following error.

thread 'bls12_381::fq::fq_repr_tests' panicked at 'assertion failed: `(left == right)`
  left: `FqRepr([5457830654796382876, 14052294085650741142, 9037930377914938456, 17127803672399921366, 8651480755814397574, 10649476550251866400])`,
 right: `FqRepr([10649476550251866400, 8651480755814397574, 17127803672399921366, 9037930377914938456, 14052294085650741142, 5457830654796382876])`', pairing/src/tests/repr.rs:53:13
note: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
test bls12_381::fq::fq_repr_tests ... FAILED

Ensure if `reader` is consumed in no_std

reader.read(g1_repr.as_mut())?;
let a = g1_repr
.into_affine()
.map_err(|_| io::Error::InvalidData)
.and_then(|e| if e.is_zero() {
Err(io::Error::PointInfinity)
} else {
Ok(e)
})?;
reader.read(g2_repr.as_mut())?;
let b = g2_repr
.into_affine()
.map_err(|_| io::Error::InvalidData)
.and_then(|e| if e.is_zero() {
Err(io::Error::PointInfinity)
} else {
Ok(e)
})?;
reader.read(g1_repr.as_mut())?;
let c = g1_repr
.into_affine()
.map_err(|_| io::Error::InvalidData)
.and_then(|e| if e.is_zero() {
Err(io::Error::PointInfinity)
} else {
Ok(e)
})?;

Each of read function should consume the reader data.

Use travis CI with wasm files in gitignore

wasm files are included here.

// code: include_bytes!("../runtime/wasm/target/wasm32-unknown-unknown/release/node_template_runtime_wasm.compact.wasm").to_vec(),
code: include_bytes!("../runtime/wasm/target/wasm32-unknown-unknown/release/zero_chain_runtime_wasm.wasm").to_vec(),

// include_bytes!("../runtime/wasm/target/wasm32-unknown-unknown/release/node_template_runtime_wasm.compact.wasm")
include_bytes!("../runtime/wasm/target/wasm32-unknown-unknown/release/zero_chain_runtime_wasm.wasm")

Refs:

[Part 1] Define parameters of confidential transfers and inputs of zk proof

parameters of confidential transfers

  • commitment root (anchor)
    A treestate consists of a note commitment tree and a nullifier set. The nullifier set is always updated together with the note commitment tree.
    The input treestate of each subsequent transaction in a block is the output treestate of the immediately preceding transaction.
    Namely, an anchor is the output treestate of either a previous block, or a previous JoinSplit transfer in this transaction

  • nullifier
    nullifier for the input note.

  • Note commitment:
    note commitment for the output note.

  • public key
    a key agreement public key, used to derive the key for encryption of the transmitted notes ciphertext.

  • random
    a seed that must be chosen independently at random for each transactions.

  • tag
    a tag that bind h_sig to each private key of the input notes
    where h_sig = hash(random, nullifier, pubkey)
    In order to avoid malleability.

  • zk proof
    a zero knowledge proof

  • encrypted Note
    ciphertext components for the encrypted output note.

inputs of zk proof

primary input (public)

  • commitment root
  • nullifier
  • Note commitment
  • h_sig
  • tag

auxiliary inputs (private)

  • merkle path
  • position
  • Note_old
  • Note_new
  • private key
  • phi (for uniquness of rho)
  • merkle path enforcement

Fix the test of zk_proof byte-cast.

The test fails because the dummy_engine is not implemented the from_affine() for the test.

error logs

---- proof::tests::test_proof_into_from stdout ----
thread 'proof::tests::test_proof_into_from' panicked at 'not yet implemented', bellman-verifier/src/tests/dummy_engine.rs:400:9
note: Run with `RUST_BACKTRACE=1` for a backtrace.

fn test_proof_into_from() {
// let mut rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]);
// let proof1 = bellman_verifier::Proof::<DummyEngine> {
// a: Fr(Wrapping(3269)),
// b: Fr(Wrapping(471)),
// c: Fr(Wrapping(8383)),
// };
// let proof_b = Proof::test_from_proof(&proof1);
// println!("proof_b: {:?}", proof_b);
// let proof2 = proof_b.test_into_proof().unwrap();
// assert!(proof1 == proof2);

For wasm, add to zero-chain-proofs

bellman = { git = "https://github.com/osuketh/bellman", branch = "wasm" }
pairing = { git = "https://github.com/sorpaas/pairing", default-features = false }

Ensure if the public attributes are safe in pairing

Ensure if it is needed to change public to public(crate).

pub x: $basefield,
pub y: $basefield,
pub infinity: bool

pub struct Fq(pub FqRepr);

But if these are changed, the test of bellman-verifier would be failed because the proof is hard-coded, it cannot access as these fields are private out of the pairing crate.

let proof = Proof::<Bls12> {
a: G1Affine {
x: Fq(FqRepr([16739797345307447054, 8770073581945912782, 2136235734558249053, 15708693206467346864, 8490922573673252286, 1579948179538746271])),
y: Fq(FqRepr([6020268861830312380, 12879642226817054130, 17904268384441769431, 15221266273771162992, 5384025118770475327, 1217424206270675696])),
infinity: false
},
b: G2Affine {
x: Fq2 {
c0: Fq(FqRepr([1955900693533848923, 1207270260807916624, 10030599496790334806, 13310839817113796132, 7335494448760471336, 1520001478562200471])),
c1: Fq(FqRepr([10867545881237734656, 11292327308906943064, 4286427264655280722, 5033346395315998832, 9316987264960049565, 1093242448245841130]))
},
y: Fq2 {
c0: Fq(FqRepr([6242954237310667968, 4585560269108097072, 5517602464819718440, 11574556308726901230, 9576729709326690239, 433440758793164942])),
c1: Fq(FqRepr([11180820212476238720, 13504112200989036594, 2176986271111729977, 4481942420924131750, 16599268505710547724, 922146901424495142]))
},
infinity: false
},
c: G1Affine {
x: Fq(FqRepr([16362720867114782945, 14827736289902972547, 7987695302896742039, 14289613131851611182, 7162884718192410854, 605698044002088945])),
y: Fq(FqRepr([3093450141616622888, 7767002491037351418, 5972324121568597438, 2377138492074911281, 701452421528324862, 1373508511228186748])),
infinity: false
}
};

Protect front running attacks

Add the pending transfer.
In the confidential transfer function, add epoch_check, roll over pendings and update last_epoch.

pub fn confTransfer() {
  RollOver(sender_addr)
  RollOver(recipient_addr)
  ・・・
  balances[sender_addr] += Enc(-value)
  pending_transfer[recipient_addr] += Enc(value)
  ・・・
}

fn RollOver(addr) {
  let H = block.number
  let e = H/E
  if lastRollOver[addr] < e:
    Set balance[addr] += pending_transfer[addr]
    Set pending_transfer[addr] = (1, 1)
    Set lastRollOver[addr] = e
}

In the storage, Add pending_transfer_map and last_epoch_map

storage{
  pending_transfer: map address => pending_value
  last_epoch: map address => block_height
  ・・・
}

Add attributes for structs

In order to send the own defined struct to substrate, needed to add attributes of Encode, Decode, Default.

Make correct sig hash for the compatibility with substrate

Need to be compatible with the signed data field between signing and verifying.

In unchecked_mortal_compact_extrinsic, the signature verification is implemented here.
https://github.com/paritytech/substrate/blob/1997487ec082f436e4c3279402d4528d67c861be/core/sr-primitives/src/generic/unchecked_mortal_compact_extrinsic.rs#L85-L96

In oo7, the signing scheme is implemented here.
https://github.com/paritytech/oo7/blob/79856e56658ad2b71115af5f682ac5d71a4f9ab3/packages/oo7-substrate/src/transact.js#L27-L42

Fix key agreement

Update key agreement process for Ed25519 that is used in substrate key store.
I can not use below one because of lack of adopting Ed25519 algorithm, only X25519.
https://briansmith.org/rustdoc/ring/agreement/fn.agree_ephemeral.html

Here is the key exchange algorithm for Ed25519.
https://github.com/DaGenix/rust-crypto/blob/master/src/ed25519.rs#L132-L151

But I need to adopt for key generation of substrate.

ref: https://crypto.stackexchange.com/questions/27866/why-curve25519-for-encryption-but-ed25519-for-signatures

Implement CLI

like

init: // each account has 100 unit at the time of initialization
 	- address0: 0xaa
 	- spending_key0: 0x4ab
 	- address1: 0xab
 	- spending_key1: 0x1c8
 	・・・
 transfer 0xab<receiver> 10<amount> 0x4ab<spending_key>
 	- success
 balance 0xaa<addr> 0x4ab<spending_key>
 	- 90
 all_balances
 	- 0xaa => 0xdaf
 	- 0xab => 0xfa3
 	・・・

Inside the transfer would be

transfer(sender, receiver, amount, sk) {
 	r,v = api::get_balance(sender) // GET
 	proof = prove() // embedded params
 	enc = encrypt()
 	tx = gen_tx()
 	runtime_api::execute_block() // POST
 }

For getting the balances, needed decryption.

 get_balance(addr) -> r, v {
 	enc = get_storage(addr, from_index)
 	p = dec(enc)
 	calc(p)
 }

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.