start to split into node commonjs style modules

- no longer is the global Bitcoin used for modules
- cleaner and more maintainable code
- add more tests
This commit is contained in:
Roman Shtylman 2013-02-17 00:39:15 -05:00
parent a6f05fb505
commit 0faac29134
35 changed files with 3401 additions and 3169 deletions

46
test/address.js Normal file
View file

@ -0,0 +1,46 @@
var assert = require('assert');
var Address = require('../').Address;
test('string', function() {
var addr = '18fN1QTGWmHWCA9r2dyDH6FbMEyc7XHmQQ';
assert.equal((new Address(addr)).toString(), addr);
});
test('valid', function() {
function validate(addr, type) {
assert.ok(Address.validate(addr, type));
};
validate('1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa');
validate('1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa', 'prod');
validate('mzBc4XEFSdzCDcTxAgf6EZXgsZWpztRhef');
validate('mzBc4XEFSdzCDcTxAgf6EZXgsZWpztRhef', 'testnet');
validate('12KYrjTdVGjFMtaxERSk3gphreJ5US8aUP');
validate('12QeMLzSrB8XH8FvEzPMVoRxVAzTr5XM2y');
validate('1oNLrsHnBcR6dpaBpwz3LSwutbUNkNSjs');
validate('1SQHtwR5oJRKLfiWQ2APsAd9miUc4k2ez');
validate('116CGDLddrZhMrTwhCVJXtXQpxygTT1kHd');
// p2sh addresses
validate('3NJZLcZEEYBpxYEUGewU4knsQRn1WM5Fkt');
validate('3NJZLcZEEYBpxYEUGewU4knsQRn1WM5Fkt', 'prod');
validate('2MxKEf2su6FGAUfCEAHreGFQvEYrfYNHvL7');
validate('2MxKEf2su6FGAUfCEAHreGFQvEYrfYNHvL7', 'testnet');
});
test('invalid', function() {
function invalid(addr, type) {
assert.ok(!Address.validate(addr, type));
};
invalid('');
invalid('mzBc4XEFSdzCDcTxAgf6EZXgsZWpztRhe');
invalid('1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa', 'testnet');
invalid('mzBc4XEFSdzCDcTxAgf6EZXgsZWpztRhef', 'prod');
// invalid base58 string
invalid('%%@');
});

15
test/base58.js Normal file
View file

@ -0,0 +1,15 @@
var assert = require('assert');
var base58 = require('../').base58;
var conv = require('../').convert;
test('decode base58', function() {
var enc = '5HueCGU8rMjxEXxiPuD5BDku4MkFqeZyd4dZ1jvhTVqvbTLvyTJ';
var hex = '800c28fca386c7a227600b2fe50b7cae11ec86d3bf1fbe471be89827e19d72aa1d507a5b8d';
assert.deepEqual(base58.decode(enc), conv.hexToBytes(hex));
});
test('encode base58', function() {
var enc = '5HueCGU8rMjxEXxiPuD5BDku4MkFqeZyd4dZ1jvhTVqvbTLvyTJ';
var hex = '800c28fca386c7a227600b2fe50b7cae11ec86d3bf1fbe471be89827e19d72aa1d507a5b8d';
assert.equal(base58.encode(conv.hexToBytes(hex)), enc);
});

24
test/convert.js Normal file
View file

@ -0,0 +1,24 @@
var assert = require('assert');
var conv = require('../').convert;
var bytesToHex = conv.bytesToHex;
var hexToBytes = conv.hexToBytes;
test('bytesToHex', function() {
assert.equal(bytesToHex([0, 1, 2, 255]), '000102ff');
});
test('hexToBytes', function() {
assert.deepEqual(hexToBytes('000102ff'), [0, 1, 2, 255]);
});
test('bytesToHex - hexToBytes', function() {
var bytes = [];
for (var i=0 ; i<256 ; ++i) {
bytes.push(i);
}
var hex = bytesToHex(bytes);
assert.equal(hex.length, 512);
assert.deepEqual(hexToBytes(hex), bytes);
});

20
test/ec.js Normal file
View file

@ -0,0 +1,20 @@
var assert = require('assert');
var sec = require('../src/jsbn/sec');
var ecdsa = require('../').ecdsa;
var ecparams = sec('secp256k1');
test("Point multiplication", function () {
var G = ecparams.getG();
var n = ecparams.getN();
assert.ok(G.multiply(n).isInfinity(), "Gn is infinite");
var k = ecdsa.getBigRandom(n);
var P = G.multiply(k);
assert.ok(!P.isInfinity(), "kG is not infinite");
assert.ok(P.isOnCurve(), "kG on curve");
assert.ok(P.multiply(n).isInfinity(), "kGn is infinite");
assert.ok(P.validate(), "kG validates as a public key");
});

View file

@ -1,36 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>BitcoinJS-lib Test Suite</title>
<link rel="stylesheet" href="../vendor/qunit/qunit.css" type="text/css" media="screen">
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>
<script type="text/javascript" src="../vendor/qunit/qunit.js"></script>
<script type="text/javascript" src="../src/crypto-js/crypto.js"></script>
<script type="text/javascript" src="../src/crypto-js/sha256.js"></script>
<script type="text/javascript" src="../src/jsbn/prng4.js"></script>
<script type="text/javascript" src="../src/jsbn/rng.js"></script>
<script type="text/javascript" src="../src/jsbn/jsbn.js"></script>
<script type="text/javascript" src="../src/jsbn/jsbn2.js"></script>
<script type="text/javascript" src="../src/jsbn/ec.js"></script>
<script type="text/javascript" src="../src/jsbn/sec.js"></script>
<script type="text/javascript" src="../src/events/eventemitter.js"></script>
<script type="text/javascript" src="../src/bitcoin.js"></script>
<script type="text/javascript" src="../src/util.js"></script>
<script type="text/javascript" src="../src/base58.js"></script>
<script type="text/javascript" src="../src/address.js"></script>
<script type="text/javascript" src="../src/ecdsa.js"></script>
<script type="text/javascript" src="../src/eckey.js"></script>
<script type="text/javascript" src="../src/paillier.js"></script>
<script type="text/javascript" src="test.js"></script>
</head>
<body>
<h1 id="qunit-header">BitcoinJS-lib Test Suite</h1>
<h2 id="qunit-banner"></h2>
<div id="qunit-testrunner-toolbar"></div>
<h2 id="qunit-userAgent"></h2>
<ol id="qunit-tests"></ol>
<div id="qunit-fixture"></div>
</body>
</html>

24
test/integer.js Normal file
View file

@ -0,0 +1,24 @@
var assert = require('assert');
var BigInteger = require('../').BigInteger;
var bytesToHex = require('../').convert.bytesToHex;
test('toByteArraySigned', function() {
function hex(num) {
var bytes = BigInteger.valueOf(num).toByteArraySigned();
var hex = bytesToHex(bytes);
return '0x' + hex;
}
assert.equal(hex( 0), '0x');
assert.equal(hex( 1), '0x01');
assert.equal(hex(-1), '0x81');
assert.equal(hex( 127), '0x7f');
assert.equal(hex(-127), '0xff');
assert.equal(hex( 255), '0x00ff');
assert.equal(hex(-255), '0x80ff');
assert.equal(hex( 16300), '0x3fac');
assert.equal(hex(-16300), '0xbfac');
assert.equal(hex( 62300), '0x00f35c');
assert.equal(hex(-62300), '0x80f35c');
});

35
test/key.js Normal file
View file

@ -0,0 +1,35 @@
var assert = require('assert');
var Key = require('../').Key;
var bytesToHex = require('../').convert.bytesToHex;
var hexToBytes = require('../').convert.hexToBytes;
var base58 = require('../').base58;
// get public key from private key
test('from private base58', function() {
var priv = '18e14a7b6a307f426a94f8114701e7c8e774e7f9a47e2c2035db29a206321725';
var pub = '0450863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b23522cd470243453a299fa9e77237716103abc11a1df38855ed6f2ee187e9c582ba6';
var key = Key(hexToBytes(priv));
assert.equal(bytesToHex(key.getPub()), pub);
assert.equal(key.compressed, false);
var priv = '5HwoXVkHoRM8sL2KmNRS217n1g8mPPBomrY7yehCuXC1115WWsh';
var pub = '044f355bdcb7cc0af728ef3cceb9615d90684bb5b2ca5f859ab0f0b704075871aa385b6b1b8ead809ca67454d9683fcf2ba03456d6fe2c4abe2b07f0fbdbb2f1c1';
var addr = '1MsHWS1BnwMc3tLE8G35UXsS58fKipzB7a';
var key = Key(priv);
assert.equal(key.compressed, false);
assert.equal(bytesToHex(key.getPub()), pub);
assert.equal(key.getBitcoinAddress().toString(), addr);
var priv = 'KwntMbt59tTsj8xqpqYqRRWufyjGunvhSyeMo3NTYpFYzZbXJ5Hp';
var pub = '034f355bdcb7cc0af728ef3cceb9615d90684bb5b2ca5f859ab0f0b704075871aa'
var addr = '1Q1pE5vPGEEMqRcVRMbtBK842Y6Pzo6nK9';
var key = Key(priv);
assert.equal(key.compressed, true);
assert.equal(bytesToHex(key.getPub()), pub);
assert.equal(key.getBitcoinAddress().toString(), addr);
});

1
test/mocha.opts Normal file
View file

@ -0,0 +1 @@
--ui qunit

102
test/test.js Executable file → Normal file
View file

@ -1,84 +1,50 @@
//
// Testing elliptic curve math
// -----------------------------------------------------------------------------
module("ec");
var assert = require('assert');
var bitcoinjs = require('../');
var sec = require('../src/jsbn/sec');
var BigInteger = require('../src/jsbn/jsbn');
var ecparams = getSECCurveByName("secp256k1");
var Crypto = require('../src/crypto-js/crypto');
var SecureRandom = require('../src/jsbn/rng');
var rng = new SecureRandom();
test("Classes", function () {
expect(3);
ok(ECPointFp, "ECPointFp");
ok(ECFieldElementFp, "ECFieldElementFp");
ok(ECCurveFp, "ECCurveFp");
});
test("Point multiplication", function () {
expect(5);
var G = ecparams.getG();
var n = ecparams.getN();
ok(G.multiply(n).isInfinity(), "Gn is infinite");
var k = Bitcoin.ECDSA.getBigRandom(n);
var P = G.multiply(k);
ok(!P.isInfinity(), "kG is not infinite");
ok(P.isOnCurve(), "kG on curve");
ok(P.multiply(n).isInfinity(), "kGn is infinite");
ok(P.validate(), "kG validates as a public key");
});
//
// Testing ECDSA
// -----------------------------------------------------------------------------
module("ecdsa");
test("Classes", function () {
expect(2);
ok(Bitcoin.ECDSA, "Bitcoin.ECDSA");
ok(Bitcoin.ECKey, "Bitcoin.ECKey");
});
var ecparams = sec('secp256k1');
var ECPointFp = bitcoinjs.ECPointFp;
test("Keys & Key Management", function () {
expect(5);
var s1 = new Bitcoin.ECKey();
var p1 = s1.getPub();
equals(p1.length, 65, "Public key is correct length");
var p1 = bitcoinjs.Key().getPub();
assert.equal(p1.length, 65);
var p1_q = ECPointFp.decodeFrom(ecparams.getCurve(), p1);
ok(p1_q, "Decode point from generated bytestring");
ok(p1_q.validate(), "Is a valid public point");
assert.ok(p1_q);
assert.ok(p1_q.validate());
var p2 = Crypto.util.hexToBytes(
var p2 = bitcoinjs.convert.hexToBytes(
"0486f356006a38b847bedec1bf47013776925d939d5a35a97a4d1263e550c7f1a" +
"b5aba44ab74d22892097a0e851addf07ba97e33416df5affaceeb35d5607cd23c"
);
var p2_q = ECPointFp.decodeFrom(ecparams.getCurve(), p2);
ok(p2_q, "Decode point from constant");
ok(p2_q.validate(), "Is a valid public point");
assert.ok(p2_q);
assert.ok(p2_q.validate());
});
test("Signing and Verifying", function () {
expect(7);
var s1 = new Bitcoin.ECKey();
var s1 = bitcoinjs.Key();
var sig_a = s1.sign(BigInteger.ZERO);
ok(sig_a, "Sign null");
equals(sig_a.length, 70, "Signature is correct length");
ok(s1.verify(BigInteger.ZERO, sig_a));
assert.ok(sig_a, "Sign null");
assert.ok(s1.verify(BigInteger.ZERO, sig_a));
var message = new BigInteger(1024, rng).toByteArrayUnsigned();
var hash = Crypto.SHA256(message, {asBytes: true});
var sig_b = s1.sign(hash);
ok(sig_b, "Sign random string");
equals(sig_b.length, 70, "Signature is correct length");
ok(s1.verify(hash, sig_b));
assert.ok(sig_b, "Sign random string");
assert.ok(s1.verify(hash, sig_b));
var message2 = Crypto.util.hexToBytes(
var message2 = bitcoinjs.convert.hexToBytes(
"12dce2c169986b3346827ffb2305cf393984627f5f9722a1b1368e933c8d" +
"d296653fbe5d7ac031c4962ad0eb1c4298c3b91d244e1116b4a76a130c13" +
"1e7aec7fa70184a71a2e66797052831511b93c6e8d72ae58a1980eaacb66" +
@ -86,27 +52,15 @@ test("Signing and Verifying", function () {
"3d82507b932b84e4"
);
var hash2 = Crypto.SHA256(message2, {asBytes: true});
var sig_c = Crypto.util.hexToBytes(
var sig_c = bitcoinjs.convert.hexToBytes(
"3044022038d9b8dd5c9fbf330565c1f51d72a59ba869aeb2c2001be959d3" +
"79e861ec71960220a73945f32cf90d03127d2c3410d16cee120fa1a4b4c3" +
"f273ab082801a95506c4"
);
var s2 = Crypto.util.hexToBytes(
var s2 = bitcoinjs.convert.hexToBytes(
"045a1594316e433fb91f35ef4874610d22177c3f1a1060f6c1e70a609d51" +
"b20be5795cd2a5eae0d6b872ba42db95e9afaeea3fbb89e98099575b6828" +
"609a978528"
);
ok(Bitcoin.ECDSA.verify(hash2, sig_c, s2), "Verify constant signature");
});
//
// Testing Paillier
// -----------------------------------------------------------------------------
module("paillier");
test("Classes", function () {
expect(3);
ok(Bitcoin.Paillier, "Bitcoin.Paillier");
ok(Bitcoin.Paillier.PublicKey, "Bitcoin.Paillier.PublicKey");
ok(Bitcoin.Paillier.PrivateKey, "Bitcoin.Paillier.PrivateKey");
assert.ok(bitcoinjs.ecdsa.verify(hash2, sig_c, s2), "Verify constant signature");
});