Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Split into multiple modules #211

Merged
merged 2 commits into from
Sep 21, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
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
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