Git Product home page Git Product logo

aztecprotocol / aztec-v1 Goto Github PK

View Code? Open in Web Editor NEW
633.0 36.0 104.0 81.33 MB

Public repository for the AZTEC V1 protocol. For the latest zkRollup release see here https://github.com/AztecProtocol/aztec-2-bug-bounty

License: GNU Lesser General Public License v3.0

JavaScript 63.79% Shell 0.25% Solidity 14.24% HTML 0.40% CSS 21.32%
protocol zero-knowledge-proofs ethereum aztec ethereum-blockchain blockchain privacy confidentiality

aztec-v1's Introduction

AZTEC is an efficient zero-knowledge privacy protocol. The protocol powers real world financial applications on Ethereum mainnet today. A complete explanation of AZTEC can be found in our white paper.

CircleCI Coverage Status Semantic Release Commitizen Friendly Twitter License: LGPL v3


Documentation ๐Ÿ“š

All AZTEC documentation is available on the documentation website: https://docs.aztecprotocol.com

This contains docs for the:

  • SDK
  • aztec.js
  • Starter kits, demos and code examples
  • Protocol specification

Packages ๐Ÿ“ฆ

AZTEC is maintained as a monorepo with multiple sub packages. Please find a comprehensive list below.

JavaScript Packages

Package Version Description
aztec.js npm An aggregate package combining many smaller utility packages for interacting with the AZTEC Protocol
@aztec/contract-artifacts npm AZTEC smart contract compiled artifacts
@aztec/contract-addresses npm A tiny utility library for getting known deployed contract addresses for a particular network
@aztec/dev-utils npm Dev utils to be shared across AZTEC projects and packages

Solidity Packages

Package Version Description
@aztec/protocol npm AZTEC solidity smart contracts & tests

Private Packages

Package Description
@aztec/monorepo-scripts Scripts for managing the monorepo

Usage โš’๏ธ

To create AZTEC notes and construct zero-knowledge proofs:

$ yarn add aztec.js

Other goodies:

$ yarn add @aztec/contract-artifacts
$ yarn add @aztec/contract-addresses
$ yarn add @aztec/dev-utils

To see a demo, head to this tutorial.

For more information, check out our documentation.

Contributing ๐Ÿ™‹โ€โ™€๏ธ

Requirements

  • node >=8.3
  • yarn >=1.15.2
  • solidity >=0.5.0 <0.6.0

Pre Requisites

Make sure you are using Yarn >= 1.15.2. To install using brew:

brew install yarn

Then install dependencies:

yarn install

Build

To build all packages:

$ yarn build

To build a specific package:

$ PKG=aztec.js yarn build

Watch

To re-build all packages on change:

$ yarn watch

Clean

To clean all packages:

$ yarn clean

To clean a specific package:

$ PKG=aztec.js yarn clean

Lint

To lint all packages:

$ yarn lint

To lint a specific package:

$ PKG=aztec.js yarn lint

Test

To run all tests:

$ yarn test

To run tests in a specific package:

$ PKG=aztec.js yarn test

FAQ โ“

What is the AZTEC Protocol?

The protocol enables transactions of value, where the values of the transaction are encrypted. The AZTEC protocol smart contract validator, AZTEC.sol, validates a unique zero-knowledge proof that determines the legitimacy of a transaction via a combination of homomorphic encryption and range proofs.

What is encrypted 'value'?

Instead of balances, the protocol uses AZTEC notes. A note encrypts a number that represents a value (for example a number of ERC-20 tokens). Each note has an owner, defined via an Ethereum address. In order to spend a note the owner must provide a valid ECDSA signature attesting to this.

What does this enable?

Confidential representations of ERC20-tokens

The AZTEC protocol can enable confidential transactions for any generic digital asset on Ethereum, including existing assets. Our first deployed asset enables zkDai.

Fully confidential digital assets

The AZTEC protocol can be utilized as a stand-alone confidential token, with value transfers described entirely through AZTEC join-split transactions

How much gas do these transactions cost?

The gas costs scale with the number of input and output notes in a join-split transaction. For a fully confidential transfer, with 2 input notes and 2 output notes, the gas cost is approximately 300,000 gas.

Where can I see this in action?

The AZTEC protocol is live today on the Ethereum main-net. Here is an example AZTEC join-split transaction.

Range proofs you say? How does that work?

Read the AZTEC paper here. The unique AZTEC commitment function enables the efficient construction and verification of range proofs. The protocol requires a trusted setup protocol, that generates a dataset that is required to construct AZTEC zero-knowledge proofs

The Trusted Setup

AZTEC ran Ignition, an MPC ceremony to generate a CRS for our privacy network and other zero-knowledge systems like PLONK from October 25th 2019 to the January 2nd 2020. 176 individuals and institutions took part, each generating randomness and adding it to the previous participant's contribution. If even one participant acts honestly and destroys the randomness they generated, the CRS can be trusted. You can see a recap of Ignition here.

Are AZTEC transactions anonymous as well as confidential?

The AZTEC protocol currently only supports confidentiality of amounts. We will be adding User privacy and Code privacy to the protocol and SDK.

This sounds interesting! How can I get involved?

Anybody wishing to become early members of the AZTEC network please get in touch at [email protected]

aztec-v1's People

Contributors

0x3bfc avatar arnsch avatar aztecbot avatar charlie-g-cowan avatar d1ll0n avatar dependabot-preview[bot] avatar dependabot-support avatar joeandrews avatar leilawang avatar malkevych avatar paulrberg avatar thomas-waite avatar tomafrench avatar zac-williamson avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

aztec-v1's Issues

Increase the signer.signPermit support for more Tokens

Current Behaviour

The signer.signPermit method seems to be Dai specific since the method description says Allows a user to create a signature for use in the DAI.permit() function.

And at implementation we have const domain = signer.generateDAIDomainParams(chainId, verifyingContract);

Possible Solution

Maybe passing the domain as parameter.

Context

Now i'm working on a USDC integration, which also have a permit method at its contract, see here.

ZkAsset not properly reporting information on linked token

Expected Behaviour

The token property of a ZkAsset should accurately report information on the linked token, e.g. name, symbol, decimals.

Current Behaviour

All linked tokens are reported to have a value of "0" for decimals and an empty string for name (symbol isn't included).

I'm trying to display a ZkAsset's balance in terms of its equivalent value in public tokens so I need to know the value of decimals. Currently this requires me to independently spin up a ERC20 contract instance to call these methods which, while definitely doable, isn't ideal.

Possible Solution

On instantiation of a ZkAsset with a linked token, these properties should be automatically queried and stored.

Steps to Reproduce (for bugs)

  1. Instantiate a ZkAsset
  2. Print out token property

Context

Your Environment

  • AZTEC packages and their versions: v1.10.1 of sdk

Concerns about the current trusted setup and requests regarding the white paper

Our proof of concept uses a trusted setup generated by our team internally.

The current on-chain implementation gives no reason to trust it as the trusted setup was generated in a closed fashion. People are very excited about your project, but it should be made clear that they should wait until the public MPC is conducted before they use Aztec or build anything on top of it, should they presume/require anonymity. This would be a good thing to emphasize in the README and the social media posts before someone builds something popular using the current implementation. If you care about the future security of users, please do this.

I also think that, despite Aztec being an anonymity-oriented protocol, the white paper underplays the topic of anonymity and only says "we make this and this assumption". I would like to see explicit discussion of

  • privacy attack vectors,
  • how statistical methods could reduce the anonymity of the users,
  • what an attacker is capable of in Aztec if they successfully reconstruct the toxic waste, and
  • what use cases Aztec is not suitable for.

Thank you for your work and I'm looking forward to further developments!

Calculate _proofHash parameter value for Ace.publicApprove

I am trying to simple unilateral transfer of ERC 20 tokens from one address to another using address.
For this we need to use Ace.publicApprove() method.
Question : Given a JoinsSplitProof object, how do I calculate "_proofHash" parameter value for Ace.publicApprove() method ?
test.txt

Split out constants into more descriptive objects

Problem

Constants should be split out into objects with more descriptive names. For instance, moving the EIP712 sigs into their object called signatures.

Packages to Update

  • aztec.js
  • dev-utils
  • protocol

Hoist [proofName]ABIEncoder.encodeAndExit() to top of validator contract

Summary of issue

All zero-knowledge validator contracts (JoinSplit.sol, PrivateRange.sol etc.) currently validate a proof and then, if successfully validated, call the associated ABI encoder, via [proofName]ABIEncoder.encodeAndExit(). This is to encode the proofOutputs in a standardised format, compatible with the ACE and so generate the transfer instructions.

To make the code functionality clearer this encoding function call should be hoisted to the start of the fallback function, immediately after validatePrivateRange().

Next steps

Hoist for:

  • JoinSplit.sol
  • BilateralSwap.sol
  • DividendComputation.sol
  • AdjustSupply.sol
  • PrivateRange.sol
  • PublicRange.sol

Update AZTEC note ABI to include a note type

The problem space

Currently we only support one type of AZTEC note, an UXTO-style AZTEC commitment. However, over time we will want to support different 'types' of AZTEC note.

For example, in our short-term roadmap we will be implementing El-Gamal treasury notes. These notes, and others, will need to be able to be distinguished from one another.

Solution

When computing a note's hash, we should integrate a 'type' variable into the hash, with different values mapping to different kinds of AZTEC notes.

In addition, we should change the note ABI encoding to include the note type. This shouldn't be too painful as we don't need to change any ABI encodings for the inputs to our validator contracts (the note type is implicit - a given proof only works with one type of note).

Updating the ABI encoding to contain the noteType

Old ABI encoding:

Offset Length Name Type Description
0x00 0x20 owner uint owner of note
0x20 0x20 noteHash bytes32 hash of note public key
0x40 - noteData bytes public key data + note metadata

New ABI encoding:

Offset Length Name Type Description
0x00 0x20 noteType uint type identifier of note
0x20 0x20 owner uint owner of note
0x40 0x20 noteHash bytes32 hash of note public key + noteType
0x40 - noteData bytes public key data + note metadata

Work to be done

  1. Update ABI encoding of JoinSplit output notes to include noteType variable
  2. Update ABI encoding of BilateralSwap output notes to include noteType variable
  3. Update ABI encoding of DividendComputation output notes to include noteType variable
  4. Update ABI encoding of AdjustSupply output notes to include noteType variable
  5. Update aztec.js abiEncoder module to use noteType variable when encoding/decoding notes

Initial list of note types

NoteType Name Description
1 UXTO Standard AZTEC note
2 TREASURY ElGamal treasury note

Announcing the AZTEC bug bounty, and a bug discovery

On the 29th of November 2018, we announced proof of concept Zero Knowledge circuit built on top of Ethereum, and deployed to Mainnet. This contract was meant as an appendix to our cryptography paper.

On Sunday 2nd of December 2018, we discovered that the contract allowed a withdrawal of $30 of DAI, through a transaction exploiting both a sub-routine of the code which was left commented in the rush to share our work with the community, and by us not fully accounting for the behaviour of ecrecover (detailed below).

These two problems are from a bug in the demo implementation of the protocolโ€Š-โ€Šthe cryptography underpinning the protocol is formally sound. At present, and until we conduct a full audit of the byte code with an external auditor, and detail the production trusted setup process, our contracts remain use-at-own-risk.

While this case was found by our local testing suite, deployment was allowed to proceed without all the tests executing, in part due to our haste to share our PoC with the community.
The $30 were placed there by the AZTEC team, and no third party was impacted.
We have released updated versions of our AZTEC smart contracts, with the relevant subroutines un-commented and the note owner validation subroutine fixed.

Our next steps are asย follows:

  • Update our deployment scripts to diminish the risks of similar human errors in future, by adding more test cases, minimal test coverage assertions and manual approval checkpoints
  • Release our bug bounty program, which is detailed here

Full exploit description

On Saturday, we noticed a transaction to our zero-knowledge DAI smart contract which drained the smart contract's DAI balance (30.6 DAI).

Naturally this should not have been possible, we noticed two problems in our deployed proof of concept smart contract that have now been addressed.

Our smart contract validator, AZTEC.sol, validates AZTEC zero-knowledge proofs by performing a series of elliptic curve arithmetic operations. There is a subroutine, validateCommitments, that checks that every input elliptic curve point is well formatted. It also checks that the integers used as inputs in the verification algorithm are well formed.

Unfortunately, this validation function was not being called for every input because the function call was commented out. Despite a test case failing because of this commented piece of code existing on our local development environment, in our haste to deploy our smart contracts before the weekend we allowed for deployment to proceed without the full battery of tests being run.

The second bug was present in our token smart contract, that created a confidential AZTEC note representation of DAI.

The method confidentialTransfer takes a set of 'input' AZTEC notes and 'output' AZTEC notes, as well as an AZTEC zero-knowledge proof that the values of these two note sets are equal.

As part of this method call, the validateInputNote subroutine is called on every input note. This subroutine checks that, for every input note, a valid ECDSA signature has been provided (the message of this signature is the AZTEC zero-knowledge proof, and it must be signed by the note owner).

AZTEC notes are stored in the noteRegistry mapping, which maps note hashes to ethereum addresses (owners). Mappings on ethereum will by default return 0 if given a key which was not initialised. This means that given an invalid note as a key, the noteRegistry mapping will return address(0x0).

Before being able to spend a note, the smart contract validates that the hash of said note in the noteRegistry maps to the address of the signer of the ECDSA signature provided in the transaction.

The address of the signer of this ECDSA signature was recovered via the ecrecover solidity helper method.

The bug in question was caused by us not fully accounting for the situation where the sender purposefully sends the ECDSA parameters which result in the ecrecover method to return address(0x0).

This results in the smart contract allowing the spending of any invalid note, since the hash of this invalid note will map to 0 in the noteRegistry mapping, which is the address recovered from the ECDSA signature.

We have deployed fixed version of our proof of concept smart contracts to addresses 0xA43F8675850ac3f60A4D4cec954F1A1B0e1dbB07 (aztec.sol), 0xcf65A4e884373Ad12cd91c8C868F1DE9DA48501F (aztecToken.sol), which have addressed these problems. Please do not use the previous smart contracts as it is possible for an attacker to withdraw all of the DAI from these contracts.

RaidGuild Request: indexed.wtf doc edits and additions

Hello blessed devs,
@thomas-waite @LeilaWang @ArnSch @PaulRBerg @zac-williamson @joeandrews @malkevych @charlie-g-cowan

We here at Raid Guild have brought you indexed.wtf and are taking care to make sure the docs we display for each Layer 2 and side-chain project are accurate and filled with information the dev teams would like to highlight specifically. Having easily accessible information about all these solutions will bring more attention to your project.

Please find the markdown for the docs for your project below.

Kindly review, edit and provide any missing details and information at your taste and discretion as project leaders.

Moving forward we aim to keep indexed.wtf as current and beneficial to developers researching the ecosystem as possible. Please feel free at any time to submit an issue or PR to update the displayed information.

Thank you for your attention to this matter.

Best,
The Indexed Army
We stand for accurate data.

www.RaidGuild.org
@chair28980 @kittyslasher

# Aztec Docs


## Name
Aztec 

## Description
Aztec is an open source layer 2 network bringing scalability and privacy too Ethereum. The Aztec protocol uses ZK-SNARK proofs to provide privacy and scaling via their [ZK-Rollup service.](https://medium.com/aztec-protocol/aztec-zkrollup-layer-2-privacy-1978e90ee3b6) To view a demo of our procject click [here.]( https://terminal.aztec.network/)

## Consensus Type
Validity Proof [(ZK-SNARK)](https://medium.com/matter-labs/optimistic-vs-zk-rollup-deep-dive-ea141e71e075)

## Tx Cost
5,000-10,000 gas

## Max TPS
300 *Test net performance*

## Governance/validator Token
None

## Transactional Token
 โงซ ETH โงซ

## Resources
[Website](https://aztec.network/)
[Github](https://github.com/AztecProtocol)
[Medium](https://medium.com/aztec-protocol/aztec-zkrollup-layer-2-privacy-1978e90ee3b6)
[Whitepaper](https://aztec-protocol.gitbook.io/aztec-documentation/technical-specification/aztec-protocol-1.0.0)
[Developer Docs](https://developers.aztec.network/)

## Social Media & Community
[Twitter](https://twitter.com/aztecnetwork)
[Telegram](https://t.me/aztecprotocol)
[Discord](https://discord.gg/UDtJr9u)
[PLONK Cafรฉ](https://www.plonk.cafe/)
[Career Opportunities](https://medium.com/aztec-protocol/were-hiring-5cd7cf5b0667)

Unused parameter in JoinSplitProof65793.encodeABI

Expected Behaviour

JoinSplitProof65793.encodeABI should not ask for a validator address

Current Behaviour

https://github.com/AztecProtocol/AZTEC/blob/2248b4b08ffbd8a1d98cfc04a4fbcb9aa23977d9/packages/aztec.js/src/proof/proofs/BALANCED/epoch0/joinSplit/index.js#L159-L167

The validator variable is only used to check if it is an Ethereum Address, it isn't used anymore in the method.

Context

The method is used in the Ganache demo, passing the same address as in JoinSplitProof65793.constructSignatures

https://github.com/AztecProtocol/aztec-ganache-starter-kit/blob/754ac4bce4e238310f357b964cc925267b186082/test/demo.js#L73-L77

But it goes against the documentation of both methods (this is what raised my concerns):

verifyingContract  | string | Ethereum address of the ZkAsset contract, from which confidentialTransfer() is called

vs

validator | string | Ethereum address of the join-split validator contract

note.fromEventLog failing from missing /node_modules/aztec.js/dist/mcl_c.wasm file

Expected Behaviour

To be able to run the following code using node.js

const note = require("aztec.js").note
const metadata = "0x1c6a72f049e538bb2c272529d626245da8e4380b3b78a848e7f35d54b6c4e7da27a387ec17338eefe6ab0c287807df0fd4437a3ad83190e0195e13505b609110dd6feecda50f75d733cf956c57e786976af334a9670c9dc27ce90139db3d1cf901"
note.fromEventLog(
  metadata,
  "0x0000000000000000000000000000000000000000000000000000000000000003"
).then(note1 => {
  console.log(`Note owner: ${note1.owner}`)
})

Current Behaviour

I get the following error when I run the above

/Users/nick/.nvm/versions/node/v12.11.1/bin/node /Users/nick/workspaces/aztec-test/index.js
{ Error: ENOENT: no such file or directory, open '/Users/nick/workspaces/aztectest/node_modules/aztec.js/dist/mcl_c.wasm'
    at Object.openSync (fs.js:443:3)
    at Object.readFileSync (fs.js:343:35)
    at Object.process.env.WEBPACK_WEB_ENV.t.read (/Users/nick/workspaces/aztectest/node_modules/aztec.js/dist/bundle.node.js:9:13919)
    at Object.process.env.WEBPACK_WEB_ENV.t.readBinary (/Users/nick/workspaces/aztectest/node_modules/aztec.js/dist/bundle.node.js:9:13986)
    at u (/Users/nick/workspaces/aztectest/node_modules/aztec.js/dist/bundle.node.js:9:18427)
    at t.wasmBinary.s.function.fetch.credentials (/Users/nick/workspaces/aztectest/node_modules/aztec.js/dist/bundle.node.js:9:19529)
    at new Promise (<anonymous>)
    at d (/Users/nick/workspaces/aztectest/node_modules/aztec.js/dist/bundle.node.js:9:19500)
    at f (/Users/nick/workspaces/aztectest/node_modules/aztec.js/dist/bundle.node.js:9:19965)
    at Object.t.asm (/Users/nick/workspaces/aztectest/node_modules/aztec.js/dist/bundle.node.js:9:20949)
  errno: -2,
  syscall: 'open',
  code: 'ENOENT',
  path:
   '/Users/nick/workspaces/aztec-test/node_modules/aztec.js/dist/mcl_c.wasm' }

Possible Solution

node_modules/aztec.js/dist/mcl_c.wasm needs to be included in the aztec.js bundle or referenced from the @aztec/bn128 module

My current workaround is to run the following to get the above code to work

cp ./node_modules/@aztec/bn128/dist/mcl_c.wasm ./node_modules/aztec.js/dist/mcl_c.wasm

Your Environment

  • AZTEC packages and their versions: aztec.js 0.18.0
  • Node and yarn version: node v12.11.1
  • Operating System and version: macOS 10.15.5

zk.money does not work with MetaMask + local node

Expected Behaviour

I expect to be able to use MetaMask with my locally synced Ethereum mainnet full node and to connect zk.money Aztec dapp with no issues.

Current Behaviour

I use MetaMask with a full node running on my local desktop. When I try to connect to zk.money I get an error that says I am on the wrong network, although my local node is running Ethereum mainnet and is fully synced. Most other dapps work with this setup, Aztec is one of the few that does not recognize localhost in MetaMask as a valid network.

Steps to Reproduce (for bugs)

  1. Sync Ethereum full node on local desktop
  2. Go into MetaMask and configure to connect to your locally running full node
  3. Try to connect to zk.money Aztec dapp
  4. See error message about wrong network

grammar

2nd para, 1st sentence

"the protocol is utilizes"

How to integrate the Mainnet<>Aztec bridge in solidity

I want to use the createDepositProof and createWithdrawProof in solidity so that I can transfer ERC20 tokens. The docs support only offchain transfer.

Do you have the documentation to do it using your bridge contract? Or do you plan to support this?

AztecSDK with NextJS: Compile Error

Expected Behaviour

Following the documentation should produce a working app.

Current Behaviour

When making a new NextJS project, the app does not work. I created an example project to reproduce the error at: https://github.com/justinalexandershaw/with-nextjs

You should be able to clone that repository and then run npm install to install the project dependencies, and then npm run dev to start the website on localhost:3000.

The app currently stops with the following errors:

on chrome:
- Error: missing provider 
- (argument="provider", value=undefined, code=INVALID_ARGUMENT, version=providers/5.0.21)

on brave:
- ./node_modules/@aztec/sdk/index.js 
- Critical dependency: the request of a dependency is an expression
and
- WriteError: QuotaExceededError
- at eval (webpack-internal:///./node_modules/@aztec/sdk/index.js:662:2661)

The build logs can be found here: https://github.com/justinalexandershaw/with-nextjs/blob/master/output.txt

Steps to Reproduce (for bugs)

  1. Create a new NextJS project (npx create-next-app)
  2. Install AzdecSDK (npm install @aztec/sdk)
  3. Update the webpack config for WASM:
const CopyPlugin = require('copy-webpack-plugin');
module.exports = {
  webpack: (config) => {
    config = {
      plugins: [
        new CopyPlugin({
          patterns: [
            {
              from: 'node_modules/@aztec/sdk/*.(wasm|worker.js)',
              to: '[name].[ext]',
            },
          ],
        }
      ),
    ], ...config};
    return config
  },
}
  1. Run the installation script when the app loads:
import { createWalletSdk } from '@aztec/sdk';

const rollupProviderUrl = 'https://api.aztec.network/falafel';
const aztecSdk = await createWalletSdk(window.ethereum, rollupProviderUrl);

console.info(aztecSdk.getLocalStatus());
// initState: 'UNINITIALIZED'

await aztecSdk.init();

console.info(aztecSdk.getLocalStatus());
// initState: 'INITIALIZED'

await aztecSdk.destroy();

console.info(aztecSdk.getLocalStatus());
// initState: 'DESTROYED'

Your Environment

Running on a Macbook Pro Intel 13" 2020

  • AZTEC packages and their versions: @aztec/sdk: v2.0.87
  • Node and yarn version: NodeJS v16.4.2, npm v7.18.1
  • Operating System and version: macOS Big Sur 11.4

Generation of proof approval signatures

Expected Behaviour

I expect to be able to export a proof along with an approval signature using the SDK with a similar flow to that for transactions sent by the GSN.

i.e:

  1. sdk window pops up showing joinsplit proof details
  2. user presses "Looks good!" and signs approval
  3. Proof + required approval signature is returned to application to be integrated into a transaction.

Current Behaviour

There's the option to export the constructed proof on the zkAsset.send method. This however doesn't bring up any UI elements showing the generation of the proof and no signature to submit alongside the proof.

There doesn't seem to be any method to sign these approvals in a simple way using the sdk.
I could generate the typed data and sign this proof separately but it would require the user to trust an unknown proof hash.

Possible Solution

It seems like all the code is there for signing these approvals as evidenced by the GSN integration. All that's needed is to allow a dapp to inject the address for which the approval is signed for and then export the proof + signature rather than sending the transaction. (Some UI changes would be needed to make clear that this isn't a standard approval)

Context

Currently with NoteStream, in order to create a stream I need two transactions (one to send ZkAssets to the contract and another to initialise the stream). This adds friction to this step and also introduces security issues as currently two streams could be made to point at the same note. (The security issue could be fixed with a blacklist of existing note hashes but that raises issues of frontrunning.)

Ideally I would be able to submit the stream's info alongside the proof to move notes to the contract however this requires a signature over the proof allowing the contract to move these notes.

The automated release is failing ๐Ÿšจ

๐Ÿšจ The automated release from the develop branch failed. ๐Ÿšจ

I recommend you give this issue a high priority, so other packages depending on you could benefit from your bug fixes and new features.

You can find below the list of errors reported by semantic-release. Each one of them has to be resolved in order to automatically publish your package. Iโ€™m sure you can resolve this ๐Ÿ’ช.

Errors are usually caused by a misconfiguration or an authentication problem. With each error reported below you will find explanation and guidance to help you to resolve it.

Once all the errors are resolved, semantic-release will release your package the next time you push a commit to the develop branch. You can also manually restart the failed CI job that runs semantic-release.

If you are not sure how to resolve this, here is some links that can help you:

If those donโ€™t help, or if this issue is reporting something you think isnโ€™t right, you can always ask the humans behind semantic-release.


No npm token specified.

An npm token must be created and set in the NPM_TOKEN environment variable on your CI environment.

Please make sure to create an npm token and to set it in the NPM_TOKEN environment variable on your CI environment. The token must allow to publish to the registry https://registry.npmjs.org/.


Good luck with your project โœจ

Your semantic-release bot ๐Ÿ“ฆ๐Ÿš€

`balanceOfLinkedToken` returns an overflown number

Expected Behaviour

balanceOfLinkedToken should return a BigNumber or string

Current Behaviour

balanceOfLinkedToken returns a javascript number, which may overflow

Possible Solution

I think the customary thing to do here is to return some instance of some big number library, but returning a string should work too.

Steps to Reproduce (for bugs)

  1. Create a zkAsset in Rinkeby with the address from the docs: const asset = await window.aztec.zkAsset('0x70c23EEC80A6387464Af55bD7Ee6C8dA273C4fb4');
  2. Mint a huge amount of the linked token (0x5B7825EA998Db74E7e43736D91459C1B0f0AdcA9). I did 10000000000000000000 (1E19)
  3. Call asset.balanceOfLinkedToken()

Your Environment

I used the aztec library from https://sdk.aztecprotocol.com/aztec.js

Get rid of the old note signature

Problem

PR #68 was merged with an old note signature still present in dev-utils, that is, AZTEC_NOTE_SIGNATURE. Its value should be replaced with the contents of AZTEC_NOTE_SIGNATURE_V2 and AZTEC_NOTE_SIGNATURE_V2 should be nuked out.

The only caveat is that some tests may need to be updated after doing that, because the old signature scheme was using a challenge variable and the newest one uses a spender.

Packages to Update

  • aztec.js
  • dev-utils
  • protocol

The automated release is failing ๐Ÿšจ

๐Ÿšจ The automated release from the develop branch failed. ๐Ÿšจ

I recommend you give this issue a high priority, so other packages depending on you could benefit from your bug fixes and new features.

You can find below the list of errors reported by semantic-release. Each one of them has to be resolved in order to automatically publish your package. Iโ€™m sure you can resolve this ๐Ÿ’ช.

Errors are usually caused by a misconfiguration or an authentication problem. With each error reported below you will find explanation and guidance to help you to resolve it.

Once all the errors are resolved, semantic-release will release your package the next time you push a commit to the develop branch. You can also manually restart the failed CI job that runs semantic-release.

If you are not sure how to resolve this, here is some links that can help you:

If those donโ€™t help, or if this issue is reporting something you think isnโ€™t right, you can always ask the humans behind semantic-release.


No npm token specified.

An npm token must be created and set in the NPM_TOKEN environment variable on your CI environment.

Please make sure to create an npm token and to set it in the NPM_TOKEN environment variable on your CI environment. The token must allow to publish to the registry https://registry.npmjs.org/.


Good luck with your project โœจ

Your semantic-release bot ๐Ÿ“ฆ๐Ÿš€

Running confidentialMint() causes either "Transaction ran out of gas" or "Block Gas Limit exceeded"

Current Behaviour

The confidentialMint() function in the ZkAssetMintable.sol that I deployed on Ropsten testnet causes the following error when called using web3: Error: Transaction ran out of gas. Please provide more gas in spite of providing gasLimit as 8000000 for Ropsten testnet (and on increasing the amount, it says block Gas Limit exceeded)

Code in relevant files:

  1. The truffle-config.js file is as shown:
require("dotenv").config();

const HDWalletProvider = require("truffle-hdwallet-provider");

const createProvider = (network) => {
  if (!process.env.MNEMONIC) {
    console.log("Please set your MNEMONIC in a .env file first");
    process.exit(1);
  }
  if (!process.env.INFURA_API_KEY) {
    console.log("Please set your INFURA_API_KEY in a .env file first");
    process.exit(1);
  }
  return () => {
    return new HDWalletProvider(
      process.env.MNEMONIC,
      `https://${network}.infura.io/v3/` + process.env.INFURA_API_KEY
    );
  };
};

module.exports = {
  networks: {
   
    development: {
     host: "127.0.0.1",     // Localhost (default: none)
     port: 8545,            // Standard Ethereum port (default: none)
     network_id: "*",       // Any network (default: none)
    },

    rinkeby: {
      provider: createProvider("rinkeby"),
      network_id: 4,       // Rinkeby's id
      gas: 10000000,        // Rinkeby has a lower block limit than mainnet
      skipDryRun: true     // Skip dry run before migrations? (default: false for public nets )
    },
    ropsten: {
      provider: createProvider("ropsten"),
      network_id: 3,       // Ropsten's id
      gas: 8000000,        // Ropsten has a lower block limit than mainnet
      skipDryRun: true     // Skip dry run before migrations? (default: false for public nets )
    },
  },

  mocha: {
    
  },


  compilers: {
    solc: {
      version: "0.5.2"
    }
  }
}
  1. The test.js file is as shown:
const Web3 = require("web3");
const Tx = require("ethereumjs-tx");
require("dotenv").config();

const url = `https://ropsten.infura.io/v3/${process.env.INFURA_API_KEY}`;
const web3 = new Web3(new Web3.providers.HttpProvider(url));

const { note, proof, abiEncoder } = require('aztec.js');
const aztecArtifacts = require("@aztec/contract-artifacts");
const { getContractAddressesForNetwork, NetworkId } = require("@aztec/contract-addresses");
const secp256k1 = require('@aztec/secp256k1');

aztecAddresses = getContractAddressesForNetwork(NetworkId.Ropsten);

ace = new web3.eth.Contract(aztecArtifacts.ACE.abi, aztecAddresses.ACE);
joinSplit = new web3.eth.Contract(aztecArtifacts.JoinSplit.abi, aztecAddresses.JoinSplit);
erc20Mintable = new web3.eth.Contract(aztecArtifacts.ERC20Mintable.abi, aztecAddresses.ERC20Mintable);
confidentialToken = new web3.eth.Contract(aztecArtifacts.ZkAssetMintable.abi, process.env.CONFIDENTIAL_TOKEN_ADDRESS_ROPSTEN);

let proofs = []
const aztecAccounts = [secp256k1.generateAccount(), secp256k1.generateAccount()];

async function mintNotes() {
    let my_notes = [note.create(aztecAccounts[0].publicKey, 50), 
        note.create(aztecAccounts[0].publicKey, 0), 
        note.create(aztecAccounts[0].publicKey, 30), 
        note.create(aztecAccounts[0].publicKey, 20)]

    let account= {
        address:"0x0aFd127a0d25A4f628DcaA70781b4d3cDb4482D6",
        pvtKey: //my private key
    };

    proofs[0] =  proof.mint.encodeMintTransaction({
        newTotalMinted: my_notes[0],
        oldTotalMinted: my_notes[1],
        adjustedNotes: my_notes.slice(2,4),
        senderAddress: account.address})


    const MINT_PROOF = 66049;

    let proofOutputs = await ace.methods.validateProof(MINT_PROOF, account.address, proofs[0].proofData).call()

    let data = confidentialToken.methods.confidentialMint(MINT_PROOF, proofs[0].proofData).encodeABI();
    const nonce = await web3.eth.getTransactionCount(account.address, "pending");
    const rawTransaction = {
        "nonce" : nonce,
        "from" : account.address,
        "to" : process.env.CONFIDENTIAL_TOKEN_ADDRESS,
        "value" : "0x0",
        "gasLimit" : web3.utils.toHex(8000000),
        "gasPrice" : web3.utils.toHex(20* 1e9),
        "data" : data,
        "chainId" : web3.utils.toHex(await web3.eth.net.getId())
    };

    var txn = new Tx(rawTransaction);
    txn.sign(Buffer.from(account.pvtKey, "hex"))

    web3.eth.sendSignedTransaction('0x'+txn.serialize().toString('hex')).on('transactionHash',console.log);

}

mintNotes()

Context

My Environment

  • AZTEC packages and their versions:
    "@aztec/contract-addresses": "^1.4.0"
    "@aztec/contract-artifacts": "^1.9.1"
    "@aztec/dev-utils": "^1.8.0"
    "@aztec/protocol": "^0.6.0"
    "@aztec/secp256k1": "^1.0.0"
    "@aztec/typed-data": "^1.0.0"
    "aztec.js": "^0.7.0",
  • Node and yarn version: v10.15.0 and 1.15.2 respectively
  • Truffle version: v5.0.0
  • Operating System and version: Ubuntu 16.04

registerAZTECExtension can be front-runned with a different AZTEC address

The registerAZTECExtension function allows to register a new AZTEC account and associate it with an AZTEC address:

https://github.com/AztecProtocol/AZTEC/blob/8657927b62fd1f14e2eb0a3205147b4163328987/packages/protocol/contracts/AccountRegistry/epochs/20200106/Behaviour20200106.sol#L101-L124

The registration is protected by the signature verification implemented by recoverSignature function. However, the parameter defining the associated AZTEC address (_AZTECaddress) is not included in the signature verification:

https://github.com/AztecProtocol/AZTEC/blob/8657927b62fd1f14e2eb0a3205147b4163328987/packages/protocol/contracts/AccountRegistry/epochs/20200106/Behaviour20200106.sol#L114-L117

This allows an attacker to potentially front-run a registerAZTECExtension transaction before it is confirmed by the network. As a result of that, the attacker can easily replace the _AZTECaddress by another to cause an undesired effect for the victim user.

The PR #448 fixes this issue.

@aztec/contract-artifacts 1.12.2 cannot be required on node.js

@aztec/contract-artifacts does not work at all.

$ npm init -y
$ yarn add @aztec/contract-artifacts
$ vim test.js

just require @aztec/contract-artifacts:

require("@aztec/contract-artifacts");

Expected Behaviour

can be required

Current Behaviour

$ node test.js
internal/modules/cjs/loader.js:638
    throw err;
    ^

Error: Cannot find module '../artifacts/AdjustSupply'
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:636:15)
    at Function.Module._load (internal/modules/cjs/loader.js:562:25)
    at Module.require (internal/modules/cjs/loader.js:692:17)
    at require (internal/modules/cjs/helpers.js:25:18)
    at Object.<anonymous> (/Users/yurenju/Downloads/test/node_modules/@aztec/contract-artifacts/lib/index.js:6:20)
    at Module._compile (internal/modules/cjs/loader.js:778:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:789:10)
    at Module.load (internal/modules/cjs/loader.js:653:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
    at Function.Module._load (internal/modules/cjs/loader.js:585:3)

Possible Solution

I believe it was solved in latest version on github, possible solution is just bump a version with latest source code.

Your Environment

  • AZTEC packages and their versions: "@aztec/contract-artifacts": "^1.12.2"
  • Node and yarn version: v10.16.3
  • Truffle version: v5.0.39
  • Lerna version: N/A
  • Operating System and version: MacOS 10.14.6

this is amazing work

I encourage you to apply for grants from MakerDAO and the Ethereum Foundation.

Migration error

I tried to migrate my balance to the newer version but I get a 'Something went wrong' error.

In March I send some Ether to my Aztecs ZkMoney account. I created a second account and send my Ether from one ZkMoney account to the other ZkMoney account and back. Now I upgrade to the latest version but I can't get the Ether in my upgraded account.

Maybe I switch my account and address with the upgrade, but I can't verify that.

EDIT It works with another browser without history.

Behaviour20200106.initialize can be front-runned to block the correct deployment

The initialization of Behaviour20200106 contract (or any future implementation) requires to call the initialize function with suitable parameters:

https://github.com/AztecProtocol/AZTEC/blob/8657927b62fd1f14e2eb0a3205147b4163328987/packages/protocol/contracts/AccountRegistry/epochs/20200106/Behaviour20200106.sol#L64-L68

However, there is no access control in place to avoid an attacker to front-run this call. As a result of that, an attacker could temporarily block the initialization front-running each deployment, using invalid parameters in the initialize call.

It is recommended to carefully document this potential issue to use an extra amount of gas during the deployment.

Note.derive not setting owner

Expected Behaviour

When creating a note from an event log, the owner property should be set so it can be used in a JoinSplit proof.

const note = require("aztec.js").note
const secp256k1 = require("@aztec/secp256k1")
const metadata = "0x1c6a72f049e538bb2c272529d626245da8e4380b3b78a848e7f35d54b6c4e7da27a387ec17338eefe6ab0c287807df0fd4437a3ad83190e0195e13505b609110dd6feecda50f75d733cf956c57e786976af334a9670c9dc27ce90139db3d1cf901"
const account = secp256k1.accountFromPrivateKey(
  "0x0000000000000000000000000000000000000000000000000000000000000003"
)
note.fromEventLog(
  metadata,
  account.privateKey
).then(note1 => {
  console.log(`Note owner ${note1.owner}`)
})

Current Behaviour

The following error is thrown when the JoinSplit proof is sent to the zkAsset in a confidentialTransfer transaction

revert input note owner does not match

Possible Solution

My current workaround is to explicitly set the owner property after the note is created and before the note is used in a JoinSplit proof. For example in the above, note1.owner = account.address. This allows the confidentialTransfer transaction to succeed.

I think the better solution is for note.derive(spendingKey) to set to owner property.
https://github.com/AztecProtocol/AZTEC/blob/bad7b4bd24a7bb07968e2c7b15af750b920618ec/packages/aztec.js/src/note/index.js#L116

Your Environment

  • AZTEC packages and their versions: aztec.js 0.18.0
  • Node and yarn version: node v12.11.1

Add challenge data into AZTEC proof output objects

The problem space

Currently the bytes proofOutput object ,produced from an AZTEC validator smart contract, is used by ACE to catalog valid proofs, via its hash.

Whilst in reality almost impossible, theoretically it's possible to get different proofOutput objects from different AZTEC proofs to resolve to the same proof hash.

We can remove this possibility by adding the bytes32 challenge variable into bytes proofOutput. Every AZTEC zero-knowledge proof has a challenge variable, which is itself a hash of the input string of the AZTEC proof.

This creates a unique identifier for each AZTEC proof input string - adding it into bytes proofOutput gaurantees that the hash of proofOutput is also unique.

In order to gaurantee that multiple bytes proofOutput objects from the same proof resolve to unique hashes, successive proofOutput objects should record the hash of the previous used challenge variable, as its challenge variable.

For example, for JoinSplit and DividendComputation, there is only one proofOutput - the challenge variable can be used directly.

For BilateralSwap, there are two bytes proofOutput entries inside bytes proofOutputs. The first entry should use the challenge variable directly, the second entry should use the hash of the challenge variable.

Updating the ABI encoding to contain the challenge

Old ABI encoding:

Offset Length Name Type Description
0x00 0x20 inputNotesOffset uint offset to inputNotes
0x20 0x20 outputNotesOffset uint offset to outputNotes
0x40 0x20 publicOwner address public owner of proof tokens
0x60 0x20 publicValue int volume of public tokens
0x80 L1 inputNotes bytes inputNotes
0x80 + L1 L2 outputNotes bytes outputNotes

New ABI encoding:

Offset Length Name Type Description
0x00 0x20 inputNotesOffset uint offset to inputNotes
0x20 0x20 outputNotesOffset uint offset to outputNotes
0x40 0x20 publicOwner address public owner of proof tokens
0x60 0x20 publicValue int volume of public tokens
0x80 0x20 challenge bytes32 Fiat-Shamir pseudorandom proof challenge
0xa0 L1 inputNotes bytes inputNotes
0xa0 + L1 L2 outputNotes bytes outputNotes

Work to be done

  1. Update ABI encoding of JoinSplit output to include challenge variable
  2. Update ABI encoding of BilateralSwap output to include challenge variable
  3. Update ABI encoding of DividendComputation output to include challenge variable
  4. Update ABI encoding of AdjustSupply output to include challenge variable
  5. Update aztec.js abiEncoder module to use challenge variable when encoding/decoding proof outputs

Importing Aztec into Remix Ethereum IDE

Hello everyone ๐Ÿ‘‹๐Ÿป,
First of all, thank you for the great library.

I've developed a smart contract using Remix Ethereum IDE with Solidity language (Link of the IDE)

I was wondering how I can import Aztec library into my smart contract developed in Remix Ethereum.

Thanks.

Missing MINT_PROOF in node module

Pulling @aztec/dev-utils version 2.0.0. Seems node module is missing some constants and code related to confidential minting.

yarn init && echo 'const {proofs} = require("@aztec/dev-utils");console.log(proofs);' > main.js && yarn add @aztec/dev-utils && node main.js

Outputs:
{ JOIN_SPLIT_PROOF: '65793' }

Missing:
MINT_PROOF: '66049'; BURN_PROOF: '66305';

Pulling aztec.js version 0.6.0,
node_modules/aztec.js/lib/proof/mint is missing
node_modules/aztec.js/lib/proof/burn is missing

Your Environment

  • AZTEC packages and their versions:
    "@aztec/dev-utils": "^2.0.0",
    "aztec.js": "^0.6.0"
  }
  • Node and npm version: node: v11.13.0, npm: 6.7.0, yarn : 1.15.2

registerAZTECExtension can be front-runned with a different spending public key

The registerAZTECExtension function allows to register a new AZTEC account and associate it with a spending public key:

https://github.com/AztecProtocol/AZTEC/blob/8657927b62fd1f14e2eb0a3205147b4163328987/packages/protocol/contracts/AccountRegistry/epochs/20200106/Behaviour20200106.sol#L101-L124

The registration is protected by the signature verification implemented by recoverSignature function. However, the parameter defining the associated spending public key (_spendingPublicKey) is not included in the signature verification:

https://github.com/AztecProtocol/AZTEC/blob/8657927b62fd1f14e2eb0a3205147b4163328987/packages/protocol/contracts/AccountRegistry/epochs/20200106/Behaviour20200106.sol#L114-L117

This allows an attacker to potentially front-run a registerAZTECExtension transaction before it is confirmed by the network. As a result of that, the attacker can easily replace the _spendingPublicKey by another to cause an undesired effect for the victim user.

The PR #455 fixes this issue.

Frontrunning on registerAZTECExtension after a key compromise

The registerAZTECExtension function allows to register a new AZTEC account and associate it with an AZTEC address:

https://github.com/AztecProtocol/AZTEC/blob/8657927b62fd1f14e2eb0a3205147b4163328987/packages/protocol/contracts/AccountRegistry/epochs/20200106/Behaviour20200106.sol#L101-L124

If the user wants to change the associated AZTEC, she should call again the same function. In case of key compromise, this transaction can hint an attacker of the change to try to confirm some transactions with the compromised key.

Exploit scenario

Alice registers her public key using registerAZTECExtension with Bob's address as the designated Aztec address:

https://github.com/AztecProtocol/AZTEC/blob/8657927b62fd1f14e2eb0a3205147b4163328987/packages/protocol/contracts/AccountRegistry/epochs/20200106/Behaviour20200106.sol#L101-L124

Some time after that, an attacker compromises Bob's private key. Alice eventually notices this and calls registerAZTECExtension to change the designated Aztec address.
The attacker sees the unconfirmed transaction and can still call functions like deposit by front-running Alice call.

Recommendation

Document this potential issue. Recommend users to use an extra gas in case of a key compromise.

Speed up wallet sync (without compromising on security or privacy)

If I haven't used zk.money in a while, it takes a minute or two (or sometimes longer, it seems) to sync the wallet when I open it up.

I have been told that one way the Aztec team is thinking about addressing this is with a "sharding-based" approach. I'd be interested in learning more about the ideas here.

Another idea I have is to enable users to run their own Aztec full node outside of the browser, on a personal server in their home (like DAppNode) or somewhere in the cloud, and then pair their zk.money wallet with their externally-operated full node so that when they open the wallet, its balances are synced right away (since the externally-operated node is running 24/7 and so always synced with the chain tip).

Regardless of the method used, I can see this sync time getting longer and longer as the rollup fills with more transactions, and so for the sake of UX we'll want to figure out one or more solutions so that users can open their wallet and begin using it within a reasonable amount of time without compromising on security or privacy (i.e. no "trusted third party servers" doing the heavy lifting here).

Proof construction, error if scalars = 0?

Explanation of the issue

During proof construction, we often do not need to calculate/send the value of kBar for all notes. This is the case in bilateralSwap and privateRange, for example, where in both cases the validator infers the value from a balancing relationship.

In order to avoid sending redundant information, we currently send 'duds' - useless information to act as a placeholder for the kBar values of these particular notes. Currently, I assign the 'duds' random values.

Ideally, these should be assigned 0 - it would save both gas and makes more intuitive sense as these variables are supposed to represent no information.

However, we also run tests during proof construction that check if any of the scalars are set to 0 - it is designated unwanted behaviour. Proof construction will fail, throwing an error.

These two behaviours - the desire to transmit 'dud', zero value kBars and throwing if scalars of 0 are encountered - need reconciling.

Next steps

  1. Investigate the implications of zero valued scalars 0

Expand on gas costs

The README mentions that the gas cost is approximately 900,000 gas. It would be helpful if there were some comparisons to other transactions. Maybe compare to a standard ETH transfer (21,000, 42.9x) and a standard DAI transfer.

LibEIP712.recoverSignature() allows to replay signatures just changing the size of the signature parameter

The recoverSignature() function allows to check for message signatures using the ecrecover precompiled contract:

https://github.com/AztecProtocol/AZTEC/blob/5c70d6bb85b83c002e59ef2ca65d20e66e3f097c/packages/protocol/contracts/libs/LibEIP712.sol#L72-L79

However, the implementation permits signatures with two different sizes: 0x41 bytes and 0x60 bytes.

https://github.com/AztecProtocol/AZTEC/blob/5c70d6bb85b83c002e59ef2ca65d20e66e3f097c/packages/protocol/contracts/libs/LibEIP712.sol#L118-L128

This allows an attacker to replay an signature, just changing the size of the _signature dynamic array. On one hand, if the original _signature parameter had 0x41 bytes, an attacker can extend it to have 0x60 bytes and it should be correctly validated by recoverSignature. On the other hand, if the original _signature had 0x60 bytes, an attacker could declare as smaller one (0x41 bytes) but send extra data in the transaction. Since the function is written in assembly, the code will access the extra data and the replayed signature will be validated by recoverSignature.

The PR #447 fixes this issue.

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.