browserify / crypto-browserify Goto Github PK
View Code? Open in Web Editor NEWpartial implementation of node's `crypto` for the browser
License: MIT License
partial implementation of node's `crypto` for the browser
License: MIT License
hasn't run since September 25th
I've just added some test vectors for pbkdf2 taken from http://tools.ietf.org/rfc/rfc6070.txt
this breaks when
Input:
P = "passwordPASSWORDpassword" (24 octets)
S = "saltSALTsaltSALTsaltSALTsaltSALTsalt" (36 octets)
c = 4096
dkLen = 25
Output:
DK = 3d 2e ec 4f e4 1c 84 9b
80 c8 d8 36 62 c0 e4 4a
8b 29 1a 96 4c f2 f0 70
38 (25 octets)
I get this test output:
not ok 4 should be equal
---
operator: equal
expected: "3d2eec4fe41c849b80c8d83662c0e44a8b291a964cf2f07038"
actual: "a08f867b2f1c849b80c8d83662c0e44a8b291a96d1539a44f3"
at: Test._cb (/home/dominic/c/crypto-browserify/test/pbkdf2.js:8:11)
...
it's something to do with the lengthening, because the other settings work fine. @jdcanator I got this from your fork, any ideas?
I'm working on v2,
here is the basic idea:
require('./data.json')
this will make it easy to run exactly the same tests in node and the client. If there is a standard set of vectors, with matching output, you should use those, if not generate some from node.I minimum set of operations I'd like to support:
this will give a minimal useable subset of the node api, although, the set of algorithms is lessened.
@jducanator @jdeblese @chrisdickinson @brianloveswords @tonistiigi @juliangruber
├─┬ [email protected]
│ └── [email protected]
├─┬ [email protected]
│ ├── [email protected]
│ ├─┬ [email protected]
│ │ └── [email protected]
│ ├─┬ [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ └── [email protected]
│ ├── [email protected]
│ └─┬ [email protected]
│ ├─┬ [email protected]
│ │ └── [email protected]
│ ├── [email protected]
│ └── [email protected]
├─┬ [email protected]
│ ├── [email protected]
│ └─┬ [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ └── [email protected]
├─┬ [email protected]
│ ├── [email protected] peer invalid
│ └─┬ [email protected]
│ └── [email protected]
├── [email protected]
├── [email protected]
├─┬ [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ └─┬ [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ └── [email protected]
├── [email protected]
├── [email protected]
└─┬ [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
└── [email protected]
npm ERR! peer invalid: [email protected] /home/kpiascik/dev/crypto-browserify/node_modules/diffie-hellman/node_modules/bn.js
npm ERR! not ok code 0
This is because of browserify/diffie-hellman#5
Once diffie-hellman updates their package with a fix crypto-browserify needs to update to the latest version of diffie-hellman.
While you're publishing packages to npm, can you please push a repository URL too? Most package publishers provide a canonical Git URL where updates may be retrieved, which helps people and software tools discover the Git repository. If you're using the package.json file in the repository, you could add:
"repository" :
{ "type" : "git"
, "url" : "git://github.com/dominictarr/crypto-browserify.git"
}
Then pushing these changes to npm would be awesome.
will see if i can come up with a pr
Thoughts on using https://github.com/feross/standard across all the modules?
It'll take a bit of transitional work to get some of them up to scratch, but it will enforce a standard (ha) that is tested.
so somebody can just require like crypto-hmac or crypto-sign, Not sure the best way but hashes and random numbers are the ones that tend to be needed in the other ones so breaking those out might be a first step
pbkdf2-compat loads crypto which loads pbkdf2-compat.
Might bite one's ass when pbkdf2-compate is used explicitly, see here (repro is available):
I suggest inlining pbkdf2-compat code, circular dependencies are seriously uncool, and it's just one file anyway.
v3.4.0 has broken browserify.
Error: Cannot find module 'sha.js' from '../node_modules/browserify/node_modules/crypto-browserify'
at ../node_modules/browserify/node_modules/resolve/lib/async.js:50:17
at process (../node_modules/browserify/node_modules/resolve/lib/async.js:119:43)
at ../node_modules/browserify/node_modules/resolve/lib/async.js:128:21
at load (../node_modules/browserify/node_modules/resolve/lib/async.js:60:43)
at ../node_modules/browserify/node_modules/resolve/lib/async.js:66:22
at ../node_modules/browserify/node_modules/resolve/lib/async.js:21:47
at Object.oncomplete (fs.js:107:15)
I'm going to dig into this and see if I can find a fix
Could you release new version and update to npm.
Thanks.
I'll add a failing test case later, but I'm working on a git-in-browser implementation using browserify and I noticed that for some git objects read out of packfiles, the sha1 produced from those buffers wasn't correct (i.e., the code worked in node and produced hashes that were verifiably present in the packfile, and failed to produce the same sha1 in the browser).
I solved the issue for the time being by switching to the sha1 module (which, although it appears to take only strings, actually accepts arrays as well, which are easy enough to translate buffers to), and the results are as expected.
https://github.com/dominictarr/crypto-browserify/blob/master/rng.js#L10
The usage of Math.random in rng.js is not cryptographically safe for browsers that do not support window.crypto.getRandomValues
. It must be altered from its current design. There are a few options.
One option is presented with https://github.com/kyledrake/randjs, where I provide a mechanism for including extra entropy into a pool, which also feeds into an ARC4 cipher to add extra randomness. ARC4 is not ideal because it has known flaws, but it, combined with extra user-interaction-based entropy and Math.random is a better security story than the current implementation.
The second alternative is to remove support for browsers that do not support window.crypto.getRandomValues. This is the safer approach here, because using Math.random is not cryptographically sound. I recognize that this would punish quite a bit of users (namely whatever sad, pathetic people that still think using IE is a good idea), but what I would hate to see is people generating predictable passwords or having Bitcoin private keys discoverable because of this. Bitcore has already implemented crypto-browserify in this way, and it's a security problem that will quite possibly lead to stolen money.
The one thing I can say soundly is that the current design is potentially dangerous, and should probably be altered. At the bare minimum, developers should be warned heavily of this problem, and have a way to check if it's a problem and bail out if they choose to do so.
Thoughts?
/cc @weilu @ryanxcharles
two new methods being added in 0.11, seem to both take a key (of the correct type) and a buffer
I'm getting this error:
TypeError: Object password has no method 'copy'
When trying calling hash.digest on the browser. The code I'm running is this: https://github.com/invisiblejs/invisible-chat/blob/master/models/user.coffee#L16
Following the trace I see that digest uses Buffer.concat which in turn calls Buffer.copy which for some reason fails as it the method didn't exist (but it's there). I'm not sure if this is a crypto-browserify issue, but it started to fail like a couple of weeks ago, I presume after this was merged: 88c3ace#diff-168726dbe96b3ce427e7fedce31bb0bcR47
Since Browserify uses a much older version (https://github.com/substack/node-browserify/blob/master/package.json#L46), is there an easy way to force Browserify to use the latest version?
http://bitwiseshiftleft.github.io/sjcl/
seems like it might be good?
Any node.js lib that depends on the hash.write
and hash.end
API breaks in the browser currently.
was added in 2.3.0
When I started the crypto-browserify
project it was a simple idea: A pure javascript drop-in replacement for node's crypto
module that would run in the browser. I never really expected that we could get as feature complete as we are now - I can only take a small part of the credit for this.
At the time, getting node's crypto module to work in the browser seemed like the right idea, but in the process, I have learnt a great deal more about cryptography and now I can see we can do much better.
Edit for clarity: crypto-browserify is not the end of the story, I think we need a new project (in a new org) that aims to do bulletproof crypto, with clearly defined properties and no surprising edgecases.
node's crypto
is based on buggy standards - SHA, RSA, AES, TLS are all buggy. SHA1 is now considered to weak to be used in new protocols. SHA256 has length extension bug. RSA is unsafe without padding. AES has many insecure modes! If we are interested in building new cryptosystems (i am) then I do not think we should do so on primitives that you must understand the internal details of to use safely - What we need is a new collection of quality primitives. Hashes without length extension, signing and encrypting where the requirement for a clean nonce or padding is made explicit via the interface. Security properties must be simply stated and clearly documented.
edit for clarity: nacl has solved this problem for the primitives. It's a selection of quality primitives which have the clearest behavior, and are easy to understand with no surprises. This makes protocols built on them is easier to audit. We should use nacl, but build protocols on top of it applying the same philosophy.
Also, building your cryptosystem directly from the primitives is unwise. Even with quality primitives, there are many ways to assemble them, not all safe. Applications often need the same features, secure-channels, authentication, Encrypted storage, asymmetric encryption. These cryptomodules are assembled from the primitives, and likewise, their properties should be simply stated and clearly documented. The design process for a crypto module or protocol should be taken very seriously. Agile does work for crypto. To design a crypto protocol I think you should begin with a survey of prior art, and summarize and document the security properties. This will give you a good idea for the properties that are achiveable, you'll probably think of some new ones too! Document these, and design a protocol that realizes them. Describe the behavior your protocol will have with different kinds of attacks on it. Now you may begin to write code.
Yes, this is basically the waterfall method. Big Design Up Front. However, I am not advocating designing whole systems like this - just modules. What this is really, is a design process optimized for auditability.
I think this should probably be in the form of markdown documents with english descriptions and pseudocode.
A discussion needs to result in a easy to read document - not a back and forth issue discussion (though that is important while producing the document). Also, clear protocol design documents will be useful to developers across languages, not just javascript.
To give a concrete example of the kind of design process I am advocating have a look at what I've done here while designing a secure channel protocol: first, revew of prior art: https://github.com/ssbc/scuttlebot/wiki/secure-private-channels:-the-good,-the-bad,-and-the-ugly
then summary of desirable properties: https://github.com/ssbc/scuttlebot/wiki/desirable-properties-for-a-secure-channel then a description of a protocol that meets all those properties https://github.com/ssbc/scuttlebot/wiki/a-secure-secure-channel
Who is with me?
@calvinmetcalf @dcousens @jprichardson @lsegal @kyledrake @wolfeidau @nathan7 @ahdinosaur @substack @hij1nx @ralphtheninja @jbenet @mafintosh
it's causing build errors various places (i.e. pouchdb/geopouch#1)
In crypto-browserify randomBytes()
returns an array but in node it returns a buffer. Is it intentional or a bug? I can provide a fix.
I use webpack (webpack.github.io) for packing commonjs modules. But starting from crypto-browserify v3.2.1 I cannot pack the lib.
Here is the error:
Hash: 137e4f74f4fb1fcaa028
Version: webpack 1.4.5
Time: 459ms
Asset Size Chunks Chunk Names
pack.js 184321 0 [emitted] main
[0] ./test.js 30 {0} [built]
+ 64 hidden modules
WARNING in ./~/crypto-browserify/rng.js
Critical dependencies:
4:17-27 the request of a dependency is an expression
@ ./~/crypto-browserify/rng.js 4:17-27
WARNING in ./~/crypto-browserify/package.json
Module parse failed: /private/tmp/node_modules/crypto-browserify/package.json Line 2: Unexpected token :
You may need an appropriate loader to handle this file type.
| {
| "author": {
| "name": "Dominic Tarr",
| "email": "[email protected]",
@ ./~/crypto-browserify ^\.\/.*$
WARNING in ./~/crypto-browserify/LICENSE
Module parse failed: /private/tmp/node_modules/crypto-browserify/LICENSE Line 1: Unexpected identifier
You may need an appropriate loader to handle this file type.
| The MIT License
|
| Copyright (c) 2013 Dominic Tarr
@ ./~/crypto-browserify ^\.\/.*$
WARNING in ./~/crypto-browserify/readme.markdown
Module parse failed: /private/tmp/node_modules/crypto-browserify/readme.markdown Line 1: Unexpected token ILLEGAL
You may need an appropriate loader to handle this file type.
| # crypto-browserify
|
| A (partial) port of node's `crypto` module to the browser.
@ ./~/crypto-browserify ^\.\/.*$
WARNING in ./~/crypto-browserify/example/index.html
Module parse failed: /private/tmp/node_modules/crypto-browserify/example/index.html Line 1: Unexpected token <
You may need an appropriate loader to handle this file type.
| <!doctype html>
| <html>
| <script src=bundle.js></script>
@ ./~/crypto-browserify ^\.\/.*$
WARNING in (webpack)/~/node-libs-browser/~/crypto-browserify/rng.js
Critical dependencies:
4:17-27 the request of a dependency is an expression
@ (webpack)/~/node-libs-browser/~/crypto-browserify/rng.js 4:17-27
WARNING in (webpack)/~/node-libs-browser/~/crypto-browserify/package.json
Module parse failed: /usr/local/lib/node_modules/webpack/node_modules/node-libs-browser/node_modules/crypto-browserify/package.json Line 2: Unexpected token :
You may need an appropriate loader to handle this file type.
| {
| "author": {
| "name": "Dominic Tarr",
| "email": "[email protected]",
@ (webpack)/~/node-libs-browser/~/crypto-browserify ^\.\/.*$
WARNING in (webpack)/~/node-libs-browser/~/crypto-browserify/LICENSE
Module parse failed: /usr/local/lib/node_modules/webpack/node_modules/node-libs-browser/node_modules/crypto-browserify/LICENSE Line 1: Unexpected identifier
You may need an appropriate loader to handle this file type.
| The MIT License
|
| Copyright (c) 2013 Dominic Tarr
@ (webpack)/~/node-libs-browser/~/crypto-browserify ^\.\/.*$
WARNING in (webpack)/~/node-libs-browser/~/crypto-browserify/readme.markdown
Module parse failed: /usr/local/lib/node_modules/webpack/node_modules/node-libs-browser/node_modules/crypto-browserify/readme.markdown Line 1: Unexpected token ILLEGAL
You may need an appropriate loader to handle this file type.
| # crypto-browserify
|
| A (partial) port of node's `crypto` module to the browser.
@ (webpack)/~/node-libs-browser/~/crypto-browserify ^\.\/.*$
WARNING in (webpack)/~/node-libs-browser/~/crypto-browserify/example/index.html
Module parse failed: /usr/local/lib/node_modules/webpack/node_modules/node-libs-browser/node_modules/crypto-browserify/example/index.html Line 1: Unexpected token <
You may need an appropriate loader to handle this file type.
| <!doctype html>
| <html>
| <script src=bundle.js></script>
@ (webpack)/~/node-libs-browser/~/crypto-browserify ^\.\/.*$
ERROR in ./~/crypto-browserify/test/create-hash.js
Module not found: Error: Cannot resolve module 'fs' in /private/tmp/node_modules/crypto-browserify/test
@ ./~/crypto-browserify/test/create-hash.js 1:9-22
ERROR in ./~/crypto-browserify/test/create-hash.js
Module not found: Error: Cannot resolve module 'tape' in /private/tmp/node_modules/crypto-browserify/test
@ ./~/crypto-browserify/test/create-hash.js 2:11-26
ERROR in ./~/crypto-browserify/test/pbkdf2.js
Module not found: Error: Cannot resolve module 'tape' in /private/tmp/node_modules/crypto-browserify/test
@ ./~/crypto-browserify/test/pbkdf2.js 2:11-26
ERROR in ./~/crypto-browserify/test/create-hmac.js
Module not found: Error: Cannot resolve module 'tape' in /private/tmp/node_modules/crypto-browserify/test
@ ./~/crypto-browserify/test/create-hmac.js 2:11-26
ERROR in ./~/crypto-browserify/test/random-bytes.js
Module not found: Error: Cannot resolve module 'tape' in /private/tmp/node_modules/crypto-browserify/test
@ ./~/crypto-browserify/test/random-bytes.js 1:11-26
ERROR in ./~/crypto-browserify/test/pbkdf2.js
Module not found: Error: Cannot resolve module 'hash-test-vectors/pbkdf2' in /private/tmp/node_modules/crypto-browserify/test
@ ./~/crypto-browserify/test/pbkdf2.js 5:14-49
ERROR in ./~/crypto-browserify/test/create-hmac.js
Module not found: Error: Cannot resolve module 'hash-test-vectors/hmac' in /private/tmp/node_modules/crypto-browserify/test
@ ./~/crypto-browserify/test/create-hmac.js 5:14-47
ERROR in ./~/crypto-browserify/test/create-hash.js
Module not found: Error: Cannot resolve module 'hash-test-vectors' in /private/tmp/node_modules/crypto-browserify/test
@ ./~/crypto-browserify/test/create-hash.js 6:14-42
ERROR in (webpack)/~/node-libs-browser/~/crypto-browserify/test/create-hash.js
Module not found: Error: Cannot resolve module 'fs' in /usr/local/lib/node_modules/webpack/node_modules/node-libs-browser/node_modules/crypto-browserify/test
@ (webpack)/~/node-libs-browser/~/crypto-browserify/test/create-hash.js 1:9-22
ERROR in (webpack)/~/node-libs-browser/~/crypto-browserify/test/create-hash.js
Module not found: Error: Cannot resolve module 'tape' in /usr/local/lib/node_modules/webpack/node_modules/node-libs-browser/node_modules/crypto-browserify/test
@ (webpack)/~/node-libs-browser/~/crypto-browserify/test/create-hash.js 2:11-26
ERROR in (webpack)/~/node-libs-browser/~/crypto-browserify/test/create-hmac.js
Module not found: Error: Cannot resolve module 'tape' in /usr/local/lib/node_modules/webpack/node_modules/node-libs-browser/node_modules/crypto-browserify/test
@ (webpack)/~/node-libs-browser/~/crypto-browserify/test/create-hmac.js 2:11-26
ERROR in (webpack)/~/node-libs-browser/~/crypto-browserify/test/pbkdf2.js
Module not found: Error: Cannot resolve module 'tape' in /usr/local/lib/node_modules/webpack/node_modules/node-libs-browser/node_modules/crypto-browserify/test
@ (webpack)/~/node-libs-browser/~/crypto-browserify/test/pbkdf2.js 2:11-26
ERROR in (webpack)/~/node-libs-browser/~/crypto-browserify/test/random-bytes.js
Module not found: Error: Cannot resolve module 'tape' in /usr/local/lib/node_modules/webpack/node_modules/node-libs-browser/node_modules/crypto-browserify/test
@ (webpack)/~/node-libs-browser/~/crypto-browserify/test/random-bytes.js 1:11-26
ERROR in (webpack)/~/node-libs-browser/~/crypto-browserify/test/create-hmac.js
Module not found: Error: Cannot resolve module 'hash-test-vectors/hmac' in /usr/local/lib/node_modules/webpack/node_modules/node-libs-browser/node_modules/crypto-browserify/test
@ (webpack)/~/node-libs-browser/~/crypto-browserify/test/create-hmac.js 5:14-47
ERROR in (webpack)/~/node-libs-browser/~/crypto-browserify/test/pbkdf2.js
Module not found: Error: Cannot resolve module 'hash-test-vectors/pbkdf2' in /usr/local/lib/node_modules/webpack/node_modules/node-libs-browser/node_modules/crypto-browserify/test
@ (webpack)/~/node-libs-browser/~/crypto-browserify/test/pbkdf2.js 5:14-49
ERROR in (webpack)/~/node-libs-browser/~/crypto-browserify/test/create-hash.js
Module not found: Error: Cannot resolve module 'hash-test-vectors' in /usr/local/lib/node_modules/webpack/node_modules/node-libs-browser/node_modules/crypto-browserify/test
@ (webpack)/~/node-libs-browser/~/crypto-browserify/test/create-hash.js 6:14-42
looks like they only have the legacy methods
see #105 so you can require that by itself
sjcl as a commonjs module is used
https://github.com/bitwiseshiftleft/sjcl/blob/master/core/random.js#L456
the result is a Buffer object supposedly with 128 random items
but there are only 16 first items filled, the rest are zeros
This code expects crypto
to be available but it was never required: https://github.com/dominictarr/crypto-browserify/blob/master/rng.js#L7
damn. Broke createHmac on [email protected]
testling is not running...
I'll look into this at first opportunity, shouldn't have pushed this.
probably you should not use 2.0 yet if you need createHmac
(strange, because createHash is fine, which is used by createHmac)
got some benchmarks here
https://github.com/dominictarr/crypto-bench
comparing against other js crypto libs.
there is a bit more work to do here (graphs and stuff)
Currently this is loading browserify-sign v2, which is causing two versions of browserify-rsa, and parse-asn1 being used.
Let me know if you need more details at all.
got this almost done looking into elliptical curves and Chinese remainder algorithm are all i have left
Anyone seen this? Looks like a WAY more complete version of what you guys are trying to do here :)
this is a new thing in v11
At the very least, the test suite is bailing in Testling with:
not ok 1 Error: Uncaught TypeError: Object #<Object> has no method 'pseudoRandomBytes' on line 7540
However, the test suite will not work as-is in the browser at all, because it is trying to compare the result of the crypto-browserify
version in the repo against what require('crypto')
pulls in. Which, after running the test suite through browserify, is actually just the previous (or even current!) version of crypto-browserify
.
The test suite needs to precompile the results of all hashes and hmacs to a file that can be used for comparisons without relying on running node's crypto
module during the tests. The sha.js
module is doing that correctly.
I can haz crypto.createHash('sha512')
? :)
This issue:
I think is a browserify issue, it passes in node, but fails in browserify. I've tried two different JWT implementations and get the same results.
I've done something dumb and published a broken release more than once.
Given the seriousness of crypto, this is not acceptable, and we need a better way.
I'm thinking something along the lines of all releases should be a pull request,
which are then validated and published by another contributor.
@calvinmetcalf, you have been putting most of the work into this recently,
I could add you as an npm owner, and then one of us prepares a release, but the other one publishes it.
Alternatively, I've just added a prepublish test that would have prevented 3.4.0 getting out.
ce25939
Maybe this will be enough?
@dcousens mentions here:
browserify/pbkdf2#4 (comment)
I don't think we have a formal answer that we have commited to, but we have merged PRs that give 0.11 compat, so I guess the answer is 0.11
Can we improve this answer?
But it is listed in the browserify.transform array in package.json
https://github.com/dominictarr/crypto-browserify/blob/master/package.json#L34
Can you create tags for each (new) release? That makes it a bit easier to compare changes.
With the crypto
reference in this line - https://github.com/dominictarr/crypto-browserify/blob/master/rng.js#L4, this module isn't completely standalone when installed through npm normally. It's a minor issue but gave a few headaches working on jspm support.
Have you taken a look at http://www.w3.org/TR/WebCryptoAPI/
I've met quite recently Nadim Kobeissi @KAepora, man behind https://crypto.cat/ who also participates in developing this spec...
I recommend contacting him directly with issues related to WebCryptoAPI or crypto in web browser in general 🔑
First, sorry for the seemingly bureaucratic issue, but getting licensing right can be important.
The LICENSE file in this project implies that all code is owned by you without any extra attributions. It would be useful to aggregate and point out all extra attributions in your project, especially since the project is made up of mostly other code. A good example of where this is used is in Ruby's LEGAL file. I would do something similar including the full licenses for each of the projects. The extra attributions do not necessarily need to be in your LICENSE, but you should point to any extra attributions document if you put it somewhere else.
I've also identified some files as missing proper attributions. When licensed software is used, and that software has a LICENSE file (or similar), that LICENSE file or its contents must be also brought in verbatim (no modifications). The following files are missing the correct licensing attribution:
You could simplify the 4 issues above by creating a document similar to Ruby's LEGAL file. Since all of Paul's code (md5, sha, sha256) is under the same license, you could list all three files with the single block of verbatim license text, and then the rng.js file gets listed separately.
On a side note, I would probably not describe the project as "I found some crypto implemented in JS lying on the internet somewhere", as that doesn't give confidence that proper licensing practices were used. Incidentally, it also doesn't give much confidence that the implementations are any good. I would probably rephrase that sentence in your README and replace it to give proper attributions to the authors whose code you are happily re-using.
What if we started with just AES?
Hey, awesome project!
Is there a reason the name is listCiphers() in this module and not the same as in node.js crypto.getCiphers() ?
Maybe keep both for backwards compatibility, but it's surprising that getHashes is there and getCiphers is not...
Hi Dominic,
I tried to rebuild the example/bundle.js
with browserify test.js -o bundle.js --exports require
with browserify 1.13.1 and when firing up the index.html in a browser, I am getting the above error in the browser console.
I am not sure whether the issue is on your side or in browserify.
Regards,
Carsten
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.