Skip to content

Commit

Permalink
Split into multiple modules (#211)
Browse files Browse the repository at this point in the history
The source is now split into modules according to category, along with
the unit tests. This should make the package easier to navigate.

There are no functional changes. For the most part, things were just
moved around. A few tests were added for the index module as well, to
avoid a drop in code coverage.

The main change aside from that is the import style. We're now using
named imports everywhere rather than `* as <name>`.
  • Loading branch information
Gudahtt authored Sep 21, 2021
1 parent 0027f50 commit fa0f1a4
Show file tree
Hide file tree
Showing 12 changed files with 8,193 additions and 8,104 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -640,12 +640,6 @@ exports[`TypedDataUtils.hashStruct V4 should hash data with a recursive data typ

exports[`TypedDataUtils.hashStruct V4 should hash data with custom type 1`] = `"c52c0ee5d84264471806290a3f2c4cecfc5490626bf912d01f240d7a274b371e"`;

exports[`concatSig should concatenate an all-zero extended ECDSA signature 1`] = `"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"`;

exports[`concatSig should concatenate an extended ECDSA signature 1`] = `"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"`;

exports[`concatSig should encode an impossibly large extended ECDSA signature 1`] = `"0x000000000000000000000000000000000000000000000000001fffffffffffff000000000000000000000000000000000000000000000000001fffffffffffff1fffffffffffff"`;

exports[`signTypedData V1 example data type "address" should sign "0x0" (type "string") 1`] = `"0x1e99abd9e342fecbad308847744c6dbd49f0517c045279a793519c1e44bcd8dd10f9adb0dc64475b47787ffc0d8f007e570072c0bbe88617ed55cea0d9e7f7941b"`;

exports[`signTypedData V1 example data type "address" should sign "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB" (type "string") 1`] = `"0xd3cc76bddfcc4dcee4612be739e194a43dc4b42bee8f0e2800b5ac7fe73374c53bada433a92fc483716f54a5f72823da28e874312e616760bb9fd4b38fd75ae01b"`;
Expand Down
7 changes: 7 additions & 0 deletions src/__snapshots__/utils.test.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`concatSig should concatenate an all-zero extended ECDSA signature 1`] = `"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"`;

exports[`concatSig should concatenate an extended ECDSA signature 1`] = `"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"`;

exports[`concatSig should encode an impossibly large extended ECDSA signature 1`] = `"0x000000000000000000000000000000000000000000000000001fffffffffffff000000000000000000000000000000000000000000000000001fffffffffffff1fffffffffffff"`;
353 changes: 353 additions & 0 deletions src/encryption.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,353 @@
import {
decrypt,
decryptSafely,
encrypt,
encryptSafely,
getEncryptionPublicKey,
} from './encryption';

describe('encryption', function () {
const bob = {
ethereumPrivateKey:
'7e5374ec2ef0d91761a6e72fdf8f6ac665519bfdf6da0a2329cf0d804514b816',
encryptionPrivateKey: 'flN07C7w2Rdhpucv349qxmVRm/322gojKc8NgEUUuBY=',
encryptionPublicKey: 'C5YMNdqE4kLgxQhJO1MfuQcHP5hjVSXzamzd/TxlR0U=',
};

const secretMessage = 'My name is Satoshi Buterin';

const encryptedData = {
version: 'x25519-xsalsa20-poly1305',
nonce: '1dvWO7uOnBnO7iNDJ9kO9pTasLuKNlej',
ephemPublicKey: 'FBH1/pAEHOOW14Lu3FWkgV3qOEcuL78Zy+qW1RwzMXQ=',
ciphertext: 'f8kBcl/NCyf3sybfbwAKk/np2Bzt9lRVkZejr6uh5FgnNlH/ic62DZzy',
};

it("Getting bob's encryptionPublicKey", async function () {
const result = await getEncryptionPublicKey(bob.ethereumPrivateKey);
expect(result).toBe(bob.encryptionPublicKey);
});

// encryption test
it("Alice encrypts message with bob's encryptionPublicKey", async function () {
const result = await encrypt({
publicKey: bob.encryptionPublicKey,
data: secretMessage,
version: 'x25519-xsalsa20-poly1305',
});

expect(result.ciphertext).toHaveLength(56);
expect(result.ephemPublicKey).toHaveLength(44);
expect(result.nonce).toHaveLength(32);
expect(result.version).toBe('x25519-xsalsa20-poly1305');
});

// safe encryption test
it("Alice encryptsSafely message with bob's encryptionPublicKey", async function () {
const version = 'x25519-xsalsa20-poly1305';
const result = await encryptSafely({
publicKey: bob.encryptionPublicKey,
data: secretMessage,
version,
});

expect(result.ciphertext).toHaveLength(2732);
expect(result.ephemPublicKey).toHaveLength(44);
expect(result.nonce).toHaveLength(32);
expect(result.version).toBe('x25519-xsalsa20-poly1305');
});

// safe decryption test
it('Bob decryptSafely message that Alice encryptSafely for him', async function () {
const version = 'x25519-xsalsa20-poly1305';
const result = await encryptSafely({
publicKey: bob.encryptionPublicKey,
data: secretMessage,
version,
});

const plaintext = decryptSafely({
encryptedData: result,
privateKey: bob.ethereumPrivateKey,
});
expect(plaintext).toBe(secretMessage);
});

// decryption test
it('Bob decrypts message that Alice sent to him', function () {
const result = decrypt({
encryptedData,
privateKey: bob.ethereumPrivateKey,
});
expect(result).toBe(secretMessage);
});

it('Decryption failed because version is wrong or missing', function () {
const badVersionData = {
version: 'x256k1-aes256cbc',
nonce: '1dvWO7uOnBnO7iNDJ9kO9pTasLuKNlej',
ephemPublicKey: 'FBH1/pAEHOOW14Lu3FWkgV3qOEcuL78Zy+qW1RwzMXQ=',
ciphertext: 'f8kBcl/NCyf3sybfbwAKk/np2Bzt9lRVkZejr6uh5FgnNlH/ic62DZzy',
};

expect(() =>
decrypt({
encryptedData: badVersionData,
privateKey: bob.ethereumPrivateKey,
}),
).toThrow('Encryption type/version not supported.');
});

it('Decryption failed because nonce is wrong or missing', function () {
// encrypted data
const badNonceData = {
version: 'x25519-xsalsa20-poly1305',
nonce: '',
ephemPublicKey: 'FBH1/pAEHOOW14Lu3FWkgV3qOEcuL78Zy+qW1RwzMXQ=',
ciphertext: 'f8kBcl/NCyf3sybfbwAKk/np2Bzt9lRVkZejr6uh5FgnNlH/ic62DZzy',
};

expect(() =>
decrypt({
encryptedData: badNonceData,
privateKey: bob.ethereumPrivateKey,
}),
).toThrow('bad nonce size');
});

it('Decryption failed because ephemPublicKey is wrong or missing', function () {
// encrypted data
const badEphemData = {
version: 'x25519-xsalsa20-poly1305',
nonce: '1dvWO7uOnBnO7iNDJ9kO9pTasLuKNlej',
ephemPublicKey: 'FFFF/pAEHOOW14Lu3FWkgV3qOEcuL78Zy+qW1RwzMXQ=',
ciphertext: 'f8kBcl/NCyf3sybfbwAKk/np2Bzt9lRVkZejr6uh5FgnNlH/ic62DZzy',
};

expect(() =>
decrypt({
encryptedData: badEphemData,
privateKey: bob.ethereumPrivateKey,
}),
).toThrow('Decryption failed.');
});

it('Decryption failed because cyphertext is wrong or missing', function () {
// encrypted data
const badEphemData = {
version: 'x25519-xsalsa20-poly1305',
nonce: '1dvWO7uOnBnO7iNDJ9kO9pTasLuKNlej',
ephemPublicKey: 'FBH1/pAEHOOW14Lu3FWkgV3qOEcuL78Zy+qW1RwzMXQ=',
ciphertext: 'ffffff/NCyf3sybfbwAKk/np2Bzt9lRVkZejr6uh5FgnNlH/ic62DZzy',
};

expect(() =>
decrypt({
encryptedData: badEphemData,
privateKey: bob.ethereumPrivateKey,
}),
).toThrow('Decryption failed.');
});

describe('validation', function () {
describe('encrypt', function () {
it('should throw if passed null public key', function () {
expect(() =>
encrypt({
publicKey: null,
data: secretMessage,
version: 'x25519-xsalsa20-poly1305',
}),
).toThrow('Missing publicKey parameter');
});

it('should throw if passed undefined public key', function () {
expect(() =>
encrypt({
publicKey: undefined,
data: secretMessage,
version: 'x25519-xsalsa20-poly1305',
}),
).toThrow('Missing publicKey parameter');
});

it('should throw if passed null data', function () {
expect(() =>
encrypt({
publicKey: bob.encryptionPublicKey,
data: null,
version: 'x25519-xsalsa20-poly1305',
}),
).toThrow('Missing data parameter');
});

it('should throw if passed undefined data', function () {
expect(() =>
encrypt({
publicKey: bob.encryptionPublicKey,
data: undefined,
version: 'x25519-xsalsa20-poly1305',
}),
).toThrow('Missing data parameter');
});

it('should throw if passed null version', function () {
expect(() =>
encrypt({
publicKey: bob.encryptionPublicKey,
data: secretMessage,
version: null,
}),
).toThrow('Missing version parameter');
});

it('should throw if passed undefined version', function () {
expect(() =>
encrypt({
publicKey: bob.encryptionPublicKey,
data: secretMessage,
version: undefined,
}),
).toThrow('Missing version parameter');
});
});

describe('encryptSafely', function () {
it('should throw if passed null public key', function () {
expect(() =>
encryptSafely({
publicKey: null,
data: secretMessage,
version: 'x25519-xsalsa20-poly1305',
}),
).toThrow('Missing publicKey parameter');
});

it('should throw if passed undefined public key', function () {
expect(() =>
encryptSafely({
publicKey: undefined,
data: secretMessage,
version: 'x25519-xsalsa20-poly1305',
}),
).toThrow('Missing publicKey parameter');
});

it('should throw if passed null data', function () {
expect(() =>
encryptSafely({
publicKey: bob.encryptionPublicKey,
data: null,
version: 'x25519-xsalsa20-poly1305',
}),
).toThrow('Missing data parameter');
});

it('should throw if passed undefined data', function () {
expect(() =>
encryptSafely({
publicKey: bob.encryptionPublicKey,
data: undefined,
version: 'x25519-xsalsa20-poly1305',
}),
).toThrow('Missing data parameter');
});

it('should throw if passed null version', function () {
expect(() =>
encryptSafely({
publicKey: bob.encryptionPublicKey,
data: secretMessage,
version: null,
}),
).toThrow('Missing version parameter');
});

it('should throw if passed undefined version', function () {
expect(() =>
encryptSafely({
publicKey: bob.encryptionPublicKey,
data: secretMessage,
version: undefined,
}),
).toThrow('Missing version parameter');
});
});

describe('decrypt', function () {
it('should throw if passed null encrypted data', function () {
expect(() =>
decrypt({
encryptedData: null,
privateKey: bob.ethereumPrivateKey,
}),
).toThrow('Missing encryptedData parameter');
});

it('should throw if passed undefined encrypted data', function () {
expect(() =>
decrypt({
encryptedData: undefined,
privateKey: bob.ethereumPrivateKey,
}),
).toThrow('Missing encryptedData parameter');
});

it('should throw if passed null private key', function () {
expect(() =>
decrypt({
encryptedData,
privateKey: null,
}),
).toThrow('Missing privateKey parameter');
});

it('should throw if passed undefined private key', function () {
expect(() =>
decrypt({
encryptedData,
privateKey: undefined,
}),
).toThrow('Missing privateKey parameter');
});
});

describe('decryptSafely', function () {
it('should throw if passed null encrypted data', function () {
expect(() =>
decryptSafely({
encryptedData: null,
privateKey: bob.ethereumPrivateKey,
}),
).toThrow('Missing encryptedData parameter');
});

it('should throw if passed undefined encrypted data', function () {
expect(() =>
decryptSafely({
encryptedData: undefined,
privateKey: bob.ethereumPrivateKey,
}),
).toThrow('Missing encryptedData parameter');
});

it('should throw if passed null private key', function () {
expect(() =>
decryptSafely({
encryptedData,
privateKey: null,
}),
).toThrow('Missing privateKey parameter');
});

it('should throw if passed undefined private key', function () {
expect(() =>
decryptSafely({
encryptedData,
privateKey: undefined,
}),
).toThrow('Missing privateKey parameter');
});
});
});
});
Loading

0 comments on commit fa0f1a4

Please sign in to comment.