Skip to content

Commit

Permalink
add sign, verify and block creation functions
Browse files Browse the repository at this point in the history
  • Loading branch information
marvinroger committed Feb 18, 2018
1 parent 44fa7c8 commit ff4a71f
Show file tree
Hide file tree
Showing 12 changed files with 448 additions and 126 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
### App ###

/dist/
/native.js
/tmp/*
!/tmp/.gitkeep

### Node ###

Expand Down
12 changes: 10 additions & 2 deletions __tests__/common/data.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ const INVALID_WORKS = [
'z000000000995bc3'
]

const INVALID_ACCOUNTS = [
const INVALID_ADDRESSES = [
12,
'zrb_1mbj7xi6yrwcuwetzd5535pdqjea5rfpsoqo9nw4gxg8itycgntucp49i1nz',
'xrb_2mbj7xi6yrwcuwetzd5535pdqjea5rfpsoqo9nw4gxg8itycgntucp49i1nz',
Expand All @@ -49,12 +49,20 @@ const INVALID_AMOUNTS = [
'-1'
]

const INVALID_SIGNATURES = [
12,
'974324f8cc42da56f62fc212a17886bdcb18de363d04da84eedc99cb4a33919d14a2cf9de9d534faa6d0b91d01f0622205d898293525e692586c84f2dcf9208',
'z974324f8cc42da56f62fc212a17886bdcb18de363d04da84eedc99cb4a33919d14a2cf9de9d534faa6d0b91d01f0622205d898293525e692586c84f2dcf9208'
]

module.exports = {
INVALID_SEEDS,
INVALID_INDEXES,
INVALID_SECRET_KEYS,
INVALID_PUBLIC_KEYS,
INVALID_HASHES,
INVALID_WORKS,
INVALID_ACCOUNTS
INVALID_ADDRESSES,
INVALID_AMOUNTS,
INVALID_SIGNATURES
}
136 changes: 131 additions & 5 deletions __tests__/hash.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const nano = require('../dist/nanocurrency.cjs')
const {
INVALID_HASHES,
INVALID_ADDRESSES,
INVALID_BALANCES
INVALID_AMOUNTS
} = require('./common/data')

const VALID_SEND_BLOCK = {
Expand Down Expand Up @@ -38,45 +38,171 @@ beforeAll(nano.init)
describe('send', () => {
test('creates correct send block', () => {
expect(
nano.computeSendBlockHash(
nano.hashSendBlock(
VALID_SEND_BLOCK.previous,
VALID_SEND_BLOCK.destination,
VALID_SEND_BLOCK.balance
)
).toBe(VALID_SEND_BLOCK.hash)
})

test('throws with invalid previous', () => {
expect.assertions(INVALID_HASHES.length)
for (let invalidHash of INVALID_HASHES) {
expect(
() => nano.hashSendBlock(
invalidHash,
VALID_SEND_BLOCK.destination,
VALID_SEND_BLOCK.balance
)
).toThrowError('Previous is not valid')
}
})

test('throws with invalid destination', () => {
expect.assertions(INVALID_ADDRESSES.length)
for (let invalidAddress of INVALID_ADDRESSES) {
expect(
() => nano.hashSendBlock(
VALID_SEND_BLOCK.previous,
invalidAddress,
VALID_SEND_BLOCK.balance
)
).toThrowError('Destination is not valid')
}
})

test('throws with invalid balance', () => {
expect.assertions(INVALID_AMOUNTS.length)
for (let invalidAmount of INVALID_AMOUNTS) {
expect(
() => nano.hashSendBlock(
VALID_SEND_BLOCK.previous,
VALID_SEND_BLOCK.destination,
invalidAmount
)
).toThrowError('Balance is not valid')
}
})
})

describe('open', () => {
test('creates correct open block', () => {
expect(
nano.computeOpenBlockHash(
nano.hashOpenBlock(
VALID_OPEN_BLOCK.source,
VALID_OPEN_BLOCK.representative,
VALID_OPEN_BLOCK.account
)
).toBe(VALID_OPEN_BLOCK.hash)
})

test('throws with invalid source', () => {
expect.assertions(INVALID_HASHES.length)
for (let invalidHash of INVALID_HASHES) {
expect(
() => nano.hashOpenBlock(
invalidHash,
VALID_OPEN_BLOCK.representative,
VALID_OPEN_BLOCK.account
)
).toThrowError('Source is not valid')
}
})

test('throws with invalid representative', () => {
expect.assertions(INVALID_ADDRESSES.length)
for (let invalidAddress of INVALID_ADDRESSES) {
expect(
() => nano.hashOpenBlock(
VALID_OPEN_BLOCK.source,
invalidAddress,
VALID_OPEN_BLOCK.account
)
).toThrowError('Representative is not valid')
}
})

test('throws with invalid account', () => {
expect.assertions(INVALID_ADDRESSES.length)
for (let invalidAddress of INVALID_ADDRESSES) {
expect(
() => nano.hashOpenBlock(
VALID_OPEN_BLOCK.source,
VALID_OPEN_BLOCK.representative,
invalidAddress
)
).toThrowError('Account is not valid')
}
})
})

describe('change', () => {
test('creates correct change block', () => {
expect(
nano.computeChangeBlockHash(
nano.hashChangeBlock(
VALID_CHANGE_BLOCK.previous,
VALID_CHANGE_BLOCK.representative
)
).toBe(VALID_CHANGE_BLOCK.hash)
})

test('throws with invalid previous', () => {
expect.assertions(INVALID_HASHES.length)
for (let invalidHash of INVALID_HASHES) {
expect(
() => nano.hashChangeBlock(
invalidHash,
VALID_CHANGE_BLOCK.representative
)
).toThrowError('Previous is not valid')
}
})

test('throws with invalid representative', () => {
expect.assertions(INVALID_ADDRESSES.length)
for (let invalidAddress of INVALID_ADDRESSES) {
expect(
() => nano.hashChangeBlock(
VALID_CHANGE_BLOCK.previous,
invalidAddress
)
).toThrowError('Representative is not valid')
}
})
})

describe('receive', () => {
test('creates correct receive block', () => {
expect(
nano.computeReceiveBlockHash(
nano.hashReceiveBlock(
VALID_RECEIVE_BLOCK.previous,
VALID_RECEIVE_BLOCK.source
)
).toBe(VALID_RECEIVE_BLOCK.hash)
})

test('throws with invalid previous', () => {
expect.assertions(INVALID_HASHES.length)
for (let invalidHash of INVALID_HASHES) {
expect(
() => nano.hashReceiveBlock(
invalidHash,
VALID_RECEIVE_BLOCK.source
)
).toThrowError('Previous is not valid')
}
})

test('throws with invalid source', () => {
expect.assertions(INVALID_HASHES.length)
for (let invalidHash of INVALID_HASHES) {
expect(
() => nano.hashReceiveBlock(
VALID_RECEIVE_BLOCK.previous,
invalidHash
)
).toThrowError('Source is not valid')
}
})
})
13 changes: 11 additions & 2 deletions __tests__/keys.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,19 +27,23 @@ const KEYS = [
beforeAll(nano.init)

describe('seeds', () => {
test('generates different seeds', () => {
expect(nano.generateSeed()).not.toBe(nano.generateSeed())
test('generates different seeds', async () => {
const seed1 = await nano.generateSeed()
const seed2 = await nano.generateSeed()
expect(seed1).not.toBe(seed2)
})
})

describe('secret keys', () => {
test('creates correct secret keys', () => {
expect.assertions(KEYS.length)
for (let key of KEYS) {
expect(nano.computeSecretKey(SEED, key.index)).toBe(key.secretKey)
}
})

test('throws with invalid seeds', () => {
expect.assertions(INVALID_SEEDS.length)
for (let invalidSeed of INVALID_SEEDS) {
expect(
() => nano.computeSecretKey(invalidSeed, 0)
Expand All @@ -48,6 +52,7 @@ describe('secret keys', () => {
})

test('throws with invalid indexes', () => {
expect.assertions(INVALID_INDEXES.length)
for (let invalidIndex of INVALID_INDEXES) {
expect(
() => nano.computeSecretKey(SEED, invalidIndex)
Expand All @@ -58,12 +63,14 @@ describe('secret keys', () => {

describe('public keys', () => {
test('creates correct public keys', () => {
expect.assertions(KEYS.length)
for (let key of KEYS) {
expect(nano.computePublicKey(key.secretKey)).toBe(key.publicKey)
}
})

test('throws with invalid secret keys', () => {
expect.assertions(INVALID_SECRET_KEYS.length)
for (let invalidSecretKey of INVALID_SECRET_KEYS) {
expect(
() => nano.computePublicKey(invalidSecretKey)
Expand All @@ -74,12 +81,14 @@ describe('public keys', () => {

describe('addresses', () => {
test('creates correct addresses', () => {
expect.assertions(KEYS.length)
for (let key of KEYS) {
expect(nano.computeAddress(key.publicKey)).toBe(key.address)
}
})

test('throws with invalid public keys', () => {
expect.assertions(INVALID_PUBLIC_KEYS.length)
for (let invalidPublicKey of INVALID_PUBLIC_KEYS) {
expect(
() => nano.computeAddress(invalidPublicKey)
Expand Down
99 changes: 87 additions & 12 deletions __tests__/signature.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,95 @@
/* eslint-env jest */

const nano = require('../dist/nanocurrency.cjs')
const {
INVALID_HASHES,
INVALID_SECRET_KEYS,
INVALID_PUBLIC_KEYS,
INVALID_SIGNATURES
} = require('./common/data')

const VALID_HASH = '7f7122e843b27524f4f1d6bd14aefd1c8f01d36ae8653d37417533c0d4bc2be6'
const VALID_SECRET_KEY = '23b5e95b4c4325ed5af109bfe4acde782dbab0163591d9052963723ae8e72a09'
const VALID_PUBLIC_KEY = '4d312f604f638adf19afac6308ecbbc5881e1b6cd6f53d382775c686bca7535b'
const VALID_SIGNATURE = '4ae39add5ee6d53c81ab8c0281787d6f81b620acca37c24dd4bfdcc85df45db65e86234b2367155382951d52b57d7dc97284b1fc9914db07d5735bd307435300'
const SECRET_KEY = '0000000000000000000000000000000000000000000000000000000000000001'
const PUBLIC_KEY = 'c969ec348895a49e21824e10e6b829edea50ccc26a83ce8986a3b95d12576058'
const HASH = 'f47b23107e5f34b2ce06f562b5c435df72a533251cb414c51b2b62a8f63a00e4'
const SIGNATURE = '5974324f8cc42da56f62fc212a17886bdcb18de363d04da84eedc99cb4a33919d14a2cf9de9d534faa6d0b91d01f0622205d898293525e692586c84f2dcf9208'
const INVALID_SIGNATURE = '8029fcd2f48c685296e525392898d5022260f10d19b0d6aaf435d9ed9fc2a41d91933a4bc99cdee48ad40d363ed81bcdb68871a212cf26f65ad24cc8f4234795'

beforeAll(nano.init)

test('signs correctly', () => {
expect(
nano.computeSignature(
VALID_HASH,
VALID_SECRET_KEY,
VALID_PUBLIC_KEY
)
).toBe(VALID_SIGNATURE)
describe('sign', () => {
test('signs correctly', () => {
expect(
nano.signBlock(
HASH,
SECRET_KEY
)
).toBe(SIGNATURE)
})

test('throws with invalid hashes', () => {
expect.assertions(INVALID_HASHES.length)
for (let invalidHash of INVALID_HASHES) {
expect(
() => nano.signBlock(invalidHash, SECRET_KEY)
).toThrowError('Hash is not valid')
}
})

test('throws with invalid secret keys', () => {
expect.assertions(INVALID_SECRET_KEYS.length)
for (let invalidSecretKey of INVALID_SECRET_KEYS) {
expect(
() => nano.signBlock(HASH, invalidSecretKey)
).toThrowError('Secret key is not valid')
}
})
})

describe('verify', () => {
test('validates correct signature', () => {
expect(
nano.verifyBlock(
HASH,
SIGNATURE,
PUBLIC_KEY
)
).toBe(true)
})

test('does not validate incorrect signature', () => {
expect(
nano.verifyBlock(
HASH,
INVALID_SIGNATURE,
PUBLIC_KEY
)
).toBe(false)
})

test('throws with invalid hashes', () => {
expect.assertions(INVALID_HASHES.length)
for (let invalidHash of INVALID_HASHES) {
expect(
() => nano.verifyBlock(invalidHash, SIGNATURE, PUBLIC_KEY)
).toThrowError('Hash is not valid')
}
})

test('throws with invalid signatures', () => {
expect.assertions(INVALID_SIGNATURES.length)
for (let invalidSignature of INVALID_SIGNATURES) {
expect(
() => nano.verifyBlock(HASH, invalidSignature, PUBLIC_KEY)
).toThrowError('Signature is not valid')
}
})

test('throws with invalid public keys', () => {
expect.assertions(INVALID_PUBLIC_KEYS.length)
for (let invalidPublicKey of INVALID_PUBLIC_KEYS) {
expect(
() => nano.verifyBlock(HASH, SIGNATURE, invalidPublicKey)
).toThrowError('Public key is not valid')
}
})
})
Loading

0 comments on commit ff4a71f

Please sign in to comment.