Skip to content

Commit

Permalink
feat(ed25519.js): Move ed25519 keyPair/sign/auth functions to scoped …
Browse files Browse the repository at this point in the history
…module
  • Loading branch information
jwerle committed Jul 23, 2018
1 parent b8668fa commit 8a86697
Showing 1 changed file with 134 additions and 0 deletions.
134 changes: 134 additions & 0 deletions ed25519.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
const isBuffer = require('is-buffer')
const alloc = require('buffer-alloc-unsafe')

/* eslint-disable camelcase */
const {
crypto_sign_PUBLICKEYBYTES,
crypto_sign_SECRETKEYBYTES,
crypto_sign_SEEDBYTES,
crypto_sign_BYTES,

crypto_sign_verify_detached,
crypto_sign_seed_keypair,
crypto_sign_detached,
crypto_sign_keypair,
} = require('sodium-universal')

/**
* Generate a public and secret key pair from an optional
* seed buffer. This function calls crypto_sign_seed_keypair and
* crypto_sign_keypair internally.
*
* @public
* @param {(Buffer)} [seed]
* @return {Object}
* @throws TypeError
*/
function keyPair(seed) {
if (null === seed) {
throw new TypeError('crypto.keyPair: Seed cannot be null.')
} else if (undefined !== seed) {
if (false === isBuffer(seed)) {
throw new TypeError('crypto.keyPair: Expecting seed to be a buffer.')
} else if (0 === seed.length) {
throw new TypeError('crypto.keyPair: Cannot use empty buffer as seed.')
} else if (seed.length < crypto_sign_SEEDBYTES) {
throw new TypeError('crypto.keyPair: Seed buffer length too small. ' +
`Expecting size ${crypto_sign_SEEDBYTES}.`)
} else if (seed.length > crypto_sign_SEEDBYTES) {
throw new TypeError('crypto.keyPair: Seed buffer length too large. ' +
`Expecting size ${crypto_sign_SEEDBYTES}.`)
}
}

const publicKey = alloc(crypto_sign_PUBLICKEYBYTES)
const secretKey = alloc(crypto_sign_SECRETKEYBYTES)

if (seed) {
crypto_sign_seed_keypair(publicKey, secretKey, seed)
} else {
crypto_sign_keypair(publicKey, secretKey)
}

return { publicKey, secretKey }
}

/**
* Sign a message buffer with a secret key buffer. This function calls
* `crypto_sign_detached` on a buffer of size `crypto_sign_BYTES`.
*
* @public
* @param {Buffer} message
* @param {Buffer} secretKey
* @return {Buffer}
* @throws TypeError
*/
function sign(message, secretKey) {
if (!message || false === isBuffer(message)) {
throw new TypeError('crypto.sign: Expecting message to be a buffer.')
} else if (0 === message.length) {
throw new TypeError('crypto.sign: Cannot sign an empty message.')
}

if (!secretKey || false === isBuffer(secretKey)) {
throw new TypeError('crypto.sign: Expecting secretKey to be a buffer.')
} else if (0 === secretKey.length) {
throw new TypeError('crypto.sign: Cannot sign with an empty secretKey.')
}

const buffer = alloc(crypto_sign_BYTES)
crypto_sign_detached(buffer, message, secretKey)
return buffer
}

/**
* Verify signature for a message signed with a given
* public key. This function calls `crypto_sign_verify_detached`
* internally.
*
* @public
* @param {Buffer} signature
* @param {Buffer} message
* @param {Buffer} publicKey
* @return {Boolean}
* @throws TypeError
*/
function verify(signature, message, publicKey) {
if (false === isBuffer(signature)) {
throw new TypeError('crypto.verify: Expecting signature to be a buffer.')
} else if (0 === signature.length) {
/* eslint-disable-next-line function-paren-newline */
throw new TypeError(
'crypto.verify: Cannot verify message with an signature buffer.')
} else if (signature.length < crypto_sign_BYTES) {
throw new TypeError('crypto.verify: Signature buffer too small.')
} else if (signature.length > crypto_sign_BYTES) {
throw new TypeError('crypto.verify: Signature buffer too large.')
}

if (false === isBuffer(message)) {
throw new TypeError('crypto.verify: Expecting message to be a buffer.')
} else if (0 === message.length) {
throw new TypeError('crypto.verify: Cannot verify an empty message buffer.')
}

if (false === isBuffer(publicKey)) {
throw new TypeError('crypto.verify: Expecting publicKey to be a buffer.')
} else if (0 === publicKey.length) {
/* eslint-disable-next-line function-paren-newline */
throw new TypeError(
'crypto.verify: Cannot verify message with an publicKey buffer.')
} else if (publicKey.length < crypto_sign_PUBLICKEYBYTES) {
throw new TypeError('crypto.verify: Public key buffer too small.')
} else if (publicKey.length > crypto_sign_PUBLICKEYBYTES) {
throw new TypeError('crypto.verify: Public key buffer too large.')
}

return crypto_sign_verify_detached(signature, message, publicKey)
}

module.exports = {
keyPair,
verify,
sign,
}

0 comments on commit 8a86697

Please sign in to comment.