diff --git a/README.md b/README.md index 7418618..9ea3bf9 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,7 @@ A set of high-level APIs over PointyCastle for two-way cryptography. - [x] AES +- [x] Salsa20 - [ ] RSA ```dart diff --git a/lib/encrypt.dart b/lib/encrypt.dart index 59b3a68..020b7d6 100644 --- a/lib/encrypt.dart +++ b/lib/encrypt.dart @@ -1,6 +1,7 @@ library encrypt; export 'src/aes.dart'; +export 'src/salsa20.dart'; abstract class Algorithm { String encrypt(String plainText); diff --git a/lib/src/salsa20.dart b/lib/src/salsa20.dart new file mode 100644 index 0000000..a8dfb63 --- /dev/null +++ b/lib/src/salsa20.dart @@ -0,0 +1,44 @@ +import '../encrypt.dart'; + +import 'package:pointycastle/stream/salsa20.dart'; + +import 'package:pointycastle/api.dart' show ParametersWithIV, KeyParameter; + +import 'dart:typed_data'; + +import 'helpers.dart'; + +class Salsa20 implements Algorithm { + final String key; + final String iv; + final ParametersWithIV _params; + + final Salsa20Engine _cipher = new Salsa20Engine(); + + Salsa20(this.key, this.iv) + : _params = new ParametersWithIV( + new KeyParameter(new Uint8List.fromList(key.codeUnits)), + new Uint8List.fromList(iv.codeUnits)); + + String encrypt(String plainText) { + _cipher + ..reset() + ..init(true, _params); + + final input = new Uint8List.fromList(plainText.codeUnits); + final output = _cipher.process(input); + + return formatBytesAsHexString(output); + } + + String decrypt(String cipherText) { + _cipher + ..reset() + ..init(false, _params); + + final input = createUint8ListFromHexString(cipherText); + final output = _cipher.process(input); + + return new String.fromCharCodes(output); + } +} diff --git a/test/encrypt_test.dart b/test/encrypt_test.dart index fadb8bf..b2ec5f6 100644 --- a/test/encrypt_test.dart +++ b/test/encrypt_test.dart @@ -2,12 +2,14 @@ import 'package:encrypt/encrypt.dart'; import 'package:test/test.dart'; void main() { - group('AES', () { - final key = 'my32lengthsupersecretnooneknows1'; + final key = 'my32lengthsupersecretnooneknows1'; + final iv = '8bytesiv'; + group('AES', () { final encrypter = new Encrypter(new AES(key)); - final plainText = - 'Lorem ipsum dolor sit amet, consectetur adipiscing elit ........'; + + final plainText = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit ' + .padRight(64, '.'); final cipherText = 'db066ce180f62f020617eb720b891c1efcc48b217cb83272812a8efe3b30e7eae4373ddcede4ea77bdae77d126d95457b3759b1983bf4cb4a6a5b051a5690bdf'; @@ -17,4 +19,18 @@ void main() { test('decrypt', () => expect(encrypter.decrypt(cipherText), equals(plainText))); }); + + group('Salsa20', () { + final encrypter = new Encrypter(new Salsa20(key, iv)); + + final plainText = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit'; + final cipherText = + '5d8dae261d5a2b5960595a9480f18156bfad5f36c07c05ae59a46870d9cb1305d2502a3b35f3fc1d1977c247bee7540068efa779284161'; + + test('encrypt', + () => expect(encrypter.encrypt(plainText), equals(cipherText))); + + test('decrypt', + () => expect(encrypter.decrypt(cipherText), equals(plainText))); + }); }