Skip to content
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
3 changes: 3 additions & 0 deletions lib/cryptography_utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ export 'src/hash/hmac.dart';
export 'src/hash/keccak/keccak.dart';
export 'src/hash/pbkdf2.dart';
export 'src/hash/ripemd160.dart';
export 'src/hash/sha/hash/digest.dart';
export 'src/hash/sha/sha256/sha256.dart';
export 'src/hash/sha/sha512/sha512.dart';
export 'src/signer/export.dart';
export 'src/slip/slip.dart';
export 'src/transactions/export.dart';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import 'dart:typed_data';

import 'package:codec_utils/codec_utils.dart';
import 'package:crypto/crypto.dart';
import 'package:cryptography_utils/cryptography_utils.dart';

/// The [BitcoinP2PKHAddressEncoder] class is designed for encoding P2PKH (Pay-to-PubKey-Hash) addresses in accordance with Bitcoin.
/// P2SH addresses utilize the RIPEMD-160 and SHA-256 hash functions to generate addresses from a script's hash.
/// Through these methods, it produces addresses prefixed with '1 and encoded with Base58Check'.
class BitcoinP2PKHAddressEncoder extends ABlockchainAddressEncoder<Secp256k1PublicKey> {
static const List<int> _networkVersionBytes = <int>[0x00];

final PublicKeyMode publicKeyMode;

BitcoinP2PKHAddressEncoder({
Expand All @@ -25,7 +25,7 @@ class BitcoinP2PKHAddressEncoder extends ABlockchainAddressEncoder<Secp256k1Publ
String encodePublicKey(Secp256k1PublicKey publicKey) {
Uint8List publicKeyBytes = publicKeyMode == PublicKeyMode.compressed ? publicKey.compressed : publicKey.uncompressed;

Uint8List publicKeyFingerprint = Uint8List.fromList(sha256.convert(publicKeyBytes).bytes);
Uint8List publicKeyFingerprint = Sha256().convert(publicKeyBytes).byteList;
Uint8List publicKeyHash = Ripemd160().process(publicKeyFingerprint);

return Base58Codec.encodeWithChecksum(Uint8List.fromList(<int>[..._networkVersionBytes, ...publicKeyHash]));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import 'dart:typed_data';

import 'package:codec_utils/codec_utils.dart';
import 'package:crypto/crypto.dart';
import 'package:cryptography_utils/cryptography_utils.dart';

/// The [BitcoinP2SHAddressEncoder] class is designed for encoding P2SH (Pay-to-Script-Hash) addresses in accordance with Bitcoin.
Expand All @@ -26,11 +25,11 @@ class BitcoinP2SHAddressEncoder extends ABlockchainAddressEncoder<Secp256k1Publi
}

List<int> _addScriptSignature(Secp256k1PublicKey publicKey) {
Uint8List publicKeyFingerprint = Uint8List.fromList(sha256.convert(publicKey.compressed).bytes);
Uint8List publicKeyFingerprint = Sha256().convert(publicKey.compressed).byteList;
Uint8List publicKeyHash = Ripemd160().process(publicKeyFingerprint);

Uint8List signatureBytes = Uint8List.fromList(<int>[..._scriptBytes, ...publicKeyHash]);
Uint8List signatureFingerprint = Uint8List.fromList(sha256.convert(signatureBytes).bytes);
Uint8List signatureFingerprint = Sha256().convert(signatureBytes).byteList;
Uint8List signatureHash = Ripemd160().process(signatureFingerprint);

return signatureHash;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import 'dart:typed_data';

import 'package:codec_utils/codec_utils.dart';
import 'package:crypto/crypto.dart';
import 'package:cryptography_utils/cryptography_utils.dart';

/// The [BitcoinP2WPKHAddressEncoder] class is designed for encoding P2WPKH (Pay-to-Witness-Public-Key-Hash) addresses in accordance with Bitcoin.
Expand All @@ -24,7 +23,7 @@ class BitcoinP2WPKHAddressEncoder extends ABlockchainAddressEncoder<Secp256k1Pub

@override
String encodePublicKey(Secp256k1PublicKey publicKey) {
Uint8List publicKeyFingerprint = Uint8List.fromList(sha256.convert(publicKey.compressed).bytes);
Uint8List publicKeyFingerprint = Sha256().convert(publicKey.compressed).byteList;
Uint8List publicKeyHash = Ripemd160().process(publicKeyFingerprint);

return SegwitBech32Codec.encode(hrp, _witnessVersion, publicKeyHash);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import 'dart:typed_data';

import 'package:codec_utils/codec_utils.dart';
import 'package:crypto/crypto.dart';
import 'package:cryptography_utils/cryptography_utils.dart';

/// The [CosmosAddressEncoder] class is designed for encoding addresses in accordance with the Cosmos network.
Expand All @@ -21,7 +20,7 @@ class CosmosAddressEncoder extends ABlockchainAddressEncoder<Secp256k1PublicKey>

@override
String encodePublicKey(Secp256k1PublicKey publicKey) {
Uint8List publicKeyFingerprint = Uint8List.fromList(sha256.convert(publicKey.compressed).bytes);
Uint8List publicKeyFingerprint = Sha256().convert(publicKey.compressed).byteList;
Uint8List publicKeyHash = Ripemd160().process(publicKeyFingerprint);

return Bech32Codec.encode(Bech32Pair(hrp: hrp, data: publicKeyHash));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@

import 'dart:typed_data';

import 'package:crypto/crypto.dart';
import 'package:cryptography_utils/cryptography_utils.dart';
import 'package:cryptography_utils/src/bip/bip32/derivators/derivator_type.dart';
import 'package:cryptography_utils/src/utils/big_int_utils.dart';
Expand Down Expand Up @@ -60,7 +59,7 @@ class Secp256k1Derivator extends ALegacyDerivator<Secp256k1PrivateKey> {
Future<Secp256k1PrivateKey> deriveMasterKey(Mnemonic mnemonic) async {
LegacyMnemonicSeedGenerator seedGenerator = LegacyMnemonicSeedGenerator();
Uint8List seed = await seedGenerator.generateSeed(mnemonic);
Uint8List hmacHash = HMAC(hash: sha512, key: Bip32HMACKeys.hmacKeySecp256k1Bytes).process(seed);
Uint8List hmacHash = HMAC(hash: Sha512(), key: Bip32HMACKeys.hmacKeySecp256k1Bytes).process(seed);

Uint8List privateKey = hmacHash.sublist(0, 32);
Uint8List chainCode = hmacHash.sublist(32);
Expand Down Expand Up @@ -99,7 +98,7 @@ class Secp256k1Derivator extends ALegacyDerivator<Secp256k1PrivateKey> {
}

List<int> data = <int>[...parentSecp256k1PublicKey.compressed, ...legacyDerivationPathElement.toBytes()];
Uint8List hmacHash = HMAC(hash: sha512, key: parentBip32KeyMetadata.chainCode!).process(data);
Uint8List hmacHash = HMAC(hash: Sha512(), key: parentBip32KeyMetadata.chainCode!).process(data);

Uint8List scalarBytes = hmacHash.sublist(0, 32);
Uint8List chainCodeBytes = hmacHash.sublist(32);
Expand All @@ -125,8 +124,9 @@ class Secp256k1Derivator extends ALegacyDerivator<Secp256k1PrivateKey> {
throw ArgumentError('Cannot derive hardened key without chain code');
}

Uint8List data = Uint8List.fromList(<int>[..._hardenedPrivateKeyPrefix, ...parentSecp256k1PrivateKey.bytes, ...legacyDerivationPathElement.toBytes()]);
Uint8List hmacHash = HMAC(hash: sha512, key: parentBip32KeyMetadata.chainCode!).process(data);
Uint8List data =
Uint8List.fromList(<int>[..._hardenedPrivateKeyPrefix, ...parentSecp256k1PrivateKey.bytes, ...legacyDerivationPathElement.toBytes()]);
Uint8List hmacHash = HMAC(hash: Sha512(), key: parentBip32KeyMetadata.chainCode!).process(data);

Uint8List scalarBytes = hmacHash.sublist(0, 32);
Uint8List chainCodeBytes = hmacHash.sublist(32);
Expand Down Expand Up @@ -156,7 +156,7 @@ class Secp256k1Derivator extends ALegacyDerivator<Secp256k1PrivateKey> {
}

Uint8List data = Uint8List.fromList(<int>[...parentSecp256k1PrivateKey.publicKey.compressed, ...legacyDerivationPathElement.toBytes()]);
Uint8List hmacHash = HMAC(hash: sha512, key: parentBip32KeyMetadata.chainCode!).process(data);
Uint8List hmacHash = HMAC(hash: Sha512(), key: parentBip32KeyMetadata.chainCode!).process(data);

Uint8List scalarBytes = hmacHash.sublist(0, 32);
Uint8List chainCodeBytes = hmacHash.sublist(32);
Expand Down
3 changes: 1 addition & 2 deletions lib/src/bip/bip32/keys/a_bip32_public_key.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import 'dart:typed_data';

import 'package:codec_utils/codec_utils.dart';
import 'package:crypto/crypto.dart';
import 'package:cryptography_utils/cryptography_utils.dart';
import 'package:cryptography_utils/src/utils/big_int_utils.dart';
import 'package:equatable/equatable.dart';
Expand Down Expand Up @@ -32,7 +31,7 @@ abstract class ABip32PublicKey extends Equatable {
});

static BigInt calcFingerprint(Uint8List publicKeyBytes) {
Uint8List sha256Fingerprint = Uint8List.fromList(sha256.convert(publicKeyBytes).bytes);
Uint8List sha256Fingerprint = Sha256().convert(publicKeyBytes).byteList;
Uint8List ripemd160Fingerprint = Uint8List.fromList(Ripemd160().process(sha256Fingerprint));
return BigIntUtils.decode(ripemd160Fingerprint.sublist(0, 4));
}
Expand Down
4 changes: 1 addition & 3 deletions lib/src/bip/bip39/mnemonic.dart
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
import 'dart:typed_data';

import 'package:crypto/crypto.dart';
import 'package:cryptography_utils/cryptography_utils.dart';
import 'package:cryptography_utils/src/utils/binary_utils.dart';
import 'package:cryptography_utils/src/utils/secure_random.dart';

import 'package:equatable/equatable.dart';

/// The [Mnemonic] class is designed for handling mnemonic phrases, which are human-readable sequences of words used to generate and recover cryptographic keys.
Expand Down Expand Up @@ -77,7 +75,7 @@ class Mnemonic extends Equatable {
static String _calculateChecksum(Uint8List entropy) {
int entropyBitsLength = entropy.length * 8;
int checksumSize = entropyBitsLength ~/ 32;
List<int> hash = sha256.convert(entropy).bytes;
List<int> hash = Sha256().convert(entropy).byteList;

return BinaryUtils.bytesToBinary(hash).substring(0, checksumSize);
}
Expand Down
4 changes: 2 additions & 2 deletions lib/src/cdsa/ecdsa/signer/ecdsa_signer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,16 @@
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
import 'dart:typed_data';

import 'package:crypto/crypto.dart';
import 'package:cryptography_utils/cryptography_utils.dart';
import 'package:cryptography_utils/src/hash/sha/hash/a_hash.dart';
import 'package:cryptography_utils/src/utils/big_int_utils.dart';

/// This class implements the functionality necessary to generate and verify digital signatures using
/// the ECDSA algorithm, a cryptographic algorithm used for creating a digital signature of data
/// which can then be verified by others with the signer's public key.
class ECDSASigner {
/// The hash function used for generating the message digest.
final Hash hashFunction;
final AHash hashFunction;

/// The ECDSA private key used for signing the message.
final ECPrivateKey ecPrivateKey;
Expand Down
4 changes: 2 additions & 2 deletions lib/src/cdsa/ecdsa/signer/ecdsa_verifier.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
import 'dart:typed_data';

import 'package:crypto/crypto.dart';
import 'package:cryptography_utils/cryptography_utils.dart';
import 'package:cryptography_utils/src/hash/sha/hash/a_hash.dart';
import 'package:cryptography_utils/src/utils/big_int_utils.dart';
import 'package:cryptography_utils/src/utils/ec_point_utils.dart';

Expand All @@ -31,7 +31,7 @@ import 'package:cryptography_utils/src/utils/ec_point_utils.dart';
/// of the corresponding private key and that the data has not been altered since it was signed.
class ECDSAVerifier {
/// The hash function used for generating the message digest.
final Hash hashFunction;
final AHash hashFunction;

/// The ECDSA public key which will be used to verification.
final ECPublicKey ecPublicKey;
Expand Down
6 changes: 3 additions & 3 deletions lib/src/cdsa/ecdsa/signer/rfc6979.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,15 @@
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
import 'dart:typed_data';

import 'package:crypto/crypto.dart';
import 'package:cryptography_utils/cryptography_utils.dart';
import 'package:cryptography_utils/src/hash/sha/hash/a_hash.dart';
import 'package:cryptography_utils/src/utils/big_int_utils.dart';
import 'package:cryptography_utils/src/utils/bytes_utils.dart';

/// The `RFC6979` class implements the deterministic generation of the ephemeral key 'k' for ECDSA signatures as outlined in RFC 6979.
/// https://www.rfc-editor.org/rfc/rfc6979.html#section-3.2
class RFC6979 {
late final Hash _hashFunction;
late final AHash _hashFunction;
late final int _hLen;

late final List<int> _m;
Expand All @@ -49,7 +49,7 @@ class RFC6979 {
required BigInt d,

/// RFC6979 H parameter
required Hash hashFunction,
required AHash hashFunction,
}) {
_m = m;
_n = n;
Expand Down
10 changes: 5 additions & 5 deletions lib/src/hash/hmac.dart
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import 'dart:typed_data';

import 'package:crypto/crypto.dart';
import 'package:cryptography_utils/src/hash/sha/hash/a_hash.dart';

/// Hash-based Message Authentication Code.
/// It computes a MAC using a given hash function with a secret key and input data.
class HMAC {
final Hash hash;
final AHash hash;
late final List<int> key;

final List<Uint8List> _chunks = <Uint8List>[];
Expand Down Expand Up @@ -50,8 +50,8 @@ class HMAC {
Uint8List get digest {
Uint8List message = _chunks.fold(Uint8List(0), (Uint8List previous, Uint8List chunk) => Uint8List.fromList(previous + chunk));

List<int> innerHash = hash.convert(iKeyPad + message).bytes;
List<int> finalHash = hash.convert(oKeyPad + innerHash).bytes;
List<int> innerHash = hash.convert(iKeyPad + message).byteList;
List<int> finalHash = hash.convert(oKeyPad + innerHash).byteList;

return Uint8List.fromList(finalHash);
}
Expand All @@ -60,7 +60,7 @@ class HMAC {
Uint8List _normalizeKey(List<int> key) {
Uint8List normalizedKey = Uint8List.fromList(key);
if (normalizedKey.length > digestSize) {
normalizedKey = Uint8List.fromList(hash.convert(key).bytes);
normalizedKey = Uint8List.fromList(hash.convert(key).byteList);
}
if (normalizedKey.length < digestSize) {
List<int> padding = List<int>.filled(digestSize - normalizedKey.length, 0);
Expand Down
8 changes: 4 additions & 4 deletions lib/src/hash/pbkdf2.dart
Original file line number Diff line number Diff line change
Expand Up @@ -31,22 +31,22 @@

import 'dart:typed_data';

import 'package:crypto/crypto.dart';
import 'package:cryptography_utils/cryptography_utils.dart';
import 'package:cryptography_utils/src/hash/sha/hash/a_hash.dart';

/// The [PBKDF2] class utilizes the PBKDF2 (Password-Based Key Derivation Function 2) hashing algorithm
/// to generate secure cryptographic keys from passwords. It is frequently applied for hashing passwords
/// within databases and in blockchain technology for seed generation from mnemonics.
class PBKDF2 {
final int iterations;
final int outputLength;
final Hash hash;
final AHash hash;

PBKDF2({
this.iterations = 2048,
this.outputLength = 64,
this.hash = sha512,
});
AHash? hash,
}) : hash = hash ?? Sha512();

/// Derives a cryptographic key from the provided password and salt using the PBKDF2 algorithm.
Uint8List process(Uint8List password, Uint8List salt) {
Expand Down
50 changes: 50 additions & 0 deletions lib/src/hash/sha/hash/a_hash.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
//This class was primarily influenced by:
// Copyright 2015, the Dart project authors.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google LLC nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

import 'dart:convert';

import 'package:cryptography_utils/src/hash/sha/hash/digest.dart';
import 'package:cryptography_utils/src/hash/sha/hash/digest_sink.dart';

/// [AHash] serves as an abstraction for cryptographic hash functions, managing the conversion of byte input into a digest. It ensures a modular and structured approach to hashing, defining a standard interface for processing data in both single-pass and chunked modes.
abstract class AHash extends Converter<List<int>, Digest> {
@override
Digest convert(List<int> input) {
DigestSink digestSink = DigestSink();
startChunkedConversion(digestSink)
..add(input)
..close();
return digestSink.valueDigest;
}

@override
ByteConversionSink startChunkedConversion(Sink<Digest> sink);

int get blockSize;
}
Loading
Loading