Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 23 additions & 44 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,12 @@ const stringify = require('json-stable-stringify')
let sodium
let HASH_KEY

function _throwUninitErr () {
throw new Error(
'Initialize function must be called before using other functions from this library.'
)
function _throwUninitErr() {
throw new Error('Initialize function must be called before using other functions from this library.')
}

// Returns 32-bytes random hex string, otherwise the number of bytes can be specified as an integer
function randomBytes (bytes = 32) {
function randomBytes(bytes = 32) {
if (!sodium) _throwUninitErr()
if (!Number.isInteger(bytes) || bytes <= 0) {
throw new TypeError('Bytes must be given as integer greater than zero.')
Expand All @@ -20,12 +18,10 @@ function randomBytes (bytes = 32) {
}

// Returns the Blake2b hash of the input string or Buffer, default output type is hex
function hash (input, fmt = 'hex') {
function hash(input, fmt = 'hex') {
if (!sodium) _throwUninitErr()
if (!HASH_KEY) {
throw new Error(
'Hash key must be passed to the initialize function before .'
)
throw new Error('Hash key must be passed to the initialize function before .')
}
if (typeof input !== 'string') {
throw new TypeError('Input must be a string or buffer.')
Expand All @@ -47,20 +43,18 @@ function hash (input, fmt = 'hex') {
}

// Returns the hash of the provided object as a hex string, takes an optional second parameter to hash an object with the "sign" field
function hashObj (obj, removeSign = false) {
function hashObj(obj, removeSign = false) {
if (typeof obj !== 'object') {
throw TypeError('Input must be an object.')
}
function performHash (obj) {
function performHash(obj) {
let input = stringify(obj)
let hashed = hash(input)
return hashed
}
if (removeSign) {
if (!obj.sign) {
throw Error(
'Object must contain a sign field if removeSign is flagged true.'
)
throw Error('Object must contain a sign field if removeSign is flagged true.')
}
let signObj = obj.sign
delete obj.sign
Expand All @@ -72,7 +66,7 @@ function hashObj (obj, removeSign = false) {
}
}

function encryptAB (input, pub, sec) {
function encryptAB(input, pub, sec) {
let inputBuf, pubBuf, secBuf, pubBoxBuf, secBoxBuf, nonce, encrypted
if (!sodium) _throwUninitErr()
if (typeof input !== 'string') {
Expand Down Expand Up @@ -103,7 +97,7 @@ function encryptAB (input, pub, sec) {
return sodium.to_hex(nonce) + ':' + sodium.to_base64(encrypted)
}

function decryptAB (input, pub, sec) {
function decryptAB(input, pub, sec) {
let inputBuf, pubBuf, secBuf, pubBoxBuf, secBoxBuf, nonce, decrypted
let nonceHex, inputBase64

Expand All @@ -116,9 +110,7 @@ function decryptAB (input, pub, sec) {
nonce = sodium.from_hex(nonceHex)
inputBuf = sodium.from_base64(inputBase64)
} catch (e) {
throw new TypeError(
'Message to decrypt in must have nonce:ciphertext as hex:base64'
)
throw new TypeError('Message to decrypt in must have nonce:ciphertext as hex:base64')
}
try {
pubBuf = sodium.from_hex(pub)
Expand All @@ -134,12 +126,7 @@ function decryptAB (input, pub, sec) {
pubBoxBuf = sodium.crypto_sign_ed25519_pk_to_curve25519(pubBuf)
secBoxBuf = sodium.crypto_sign_ed25519_sk_to_curve25519(secBuf)
try {
decrypted = sodium.crypto_box_open_easy(
inputBuf,
nonce,
pubBoxBuf,
secBoxBuf
)
decrypted = sodium.crypto_box_open_easy(inputBuf, nonce, pubBoxBuf, secBoxBuf)
} catch (e) {
throw new TypeError('Could not decrypt the message')
}
Expand All @@ -148,20 +135,20 @@ function decryptAB (input, pub, sec) {
}

// Generates and retuns {publicKey, secretKey} as hex strings
function generateKeypair () {
function generateKeypair() {
let publicBox, privateBox
if (!sodium) _throwUninitErr()
let { publicKey, privateKey } = sodium.crypto_sign_keypair()
publicBox = sodium.crypto_sign_ed25519_pk_to_curve25519(publicKey)
// console.log('publicBox', publicBox)
return {
publicKey: sodium.to_hex(publicKey),
secretKey: sodium.to_hex(privateKey)
secretKey: sodium.to_hex(privateKey),
}
}

// Returns a signature obtained by signing the input hash (hex string or buffer) with the sk string
function sign (input, sk) {
function sign(input, sk) {
if (!sodium) _throwUninitErr()
let inputBuf
let skBuf
Expand All @@ -188,7 +175,7 @@ function sign (input, sk) {
Attaches a sign field to the input object, containing a signed version
of the hash of the object, along with the public key of the signer
*/
function signObj (obj, sk, pk) {
function signObj(obj, sk, pk) {
if (typeof obj !== 'object') {
throw new TypeError('Input must be an object.')
}
Expand All @@ -205,7 +192,7 @@ function signObj (obj, sk, pk) {
}

// Returns true if the hash of the input was signed by the owner of the pk
function verify (msg, sig, pk) {
function verify(msg, sig, pk) {
if (!sodium) _throwUninitErr()
if (typeof msg !== 'string') {
throw new TypeError('Message to compare must be a string.')
Expand Down Expand Up @@ -233,37 +220,29 @@ function verify (msg, sig, pk) {
let verified = sodium.to_hex(sodium.crypto_sign_open(sigBuf, pkBuf))
return verified === msg
} catch (e) {
throw new Error(
'Unable to verify provided signature with provided public key.'
)
throw new Error('Unable to verify provided signature with provided public key.')
}
}

// Returns true if the hash of the object minus the sign field matches the signed message in the sign field
function verifyObj (obj) {
function verifyObj(obj) {
if (typeof obj !== 'object') {
throw new TypeError('Input must be an object.')
}
if (!obj.sign || !obj.sign.owner || !obj.sign.sig) {
throw new Error(
'Object must contain a sign field with the following data: { owner, sig }'
)
throw new Error('Object must contain a sign field with the following data: { owner, sig }')
}
if (typeof obj.sign.owner !== 'string') {
throw new TypeError(
'Owner must be a public key represented as a hex string.'
)
throw new TypeError('Owner must be a public key represented as a hex string.')
}
if (typeof obj.sign.sig !== 'string') {
throw new TypeError(
'Signature must be a valid signature represented as a hex string.'
)
throw new TypeError('Signature must be a valid signature represented as a hex string.')
}
let objHash = hashObj(obj, true)
return verify(objHash, obj.sign.sig, obj.sign.owner)
}

async function initialize (key) {
async function initialize(key) {
await _sodium.ready
sodium = _sodium
console.log(sodium)
Expand Down
2 changes: 1 addition & 1 deletion jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ module.exports = {
coverageReporters: ['json', 'lcov', 'text', 'json-summary'],
verbose: true,
testTimeout: 10000, // Increased timeout for async operations
};
}
6 changes: 6 additions & 0 deletions prettier.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = {
singleQuote: true,
trailingComma: 'es5',
semi: false,
printWidth: 120,
}
4 changes: 2 additions & 2 deletions test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const crypto = require('./index.js');
(async () => {
const crypto = require('./index.js')
;(async () => {
try {
await crypto.initialize('69fa4195670576c0160d660c3be36556ff8d504725be8a59b5a96509e0c994bc')
console.log(crypto.randomBytes())
Expand Down
Loading
Loading