158 lines
4.1 KiB
Dart
158 lines
4.1 KiB
Dart
// See file LICENSE for more information.
|
|
|
|
library api.asymmetric;
|
|
|
|
import 'dart:typed_data';
|
|
|
|
import 'package:pointycastle/api.dart';
|
|
|
|
/// Base class for asymmetric keys in RSA
|
|
abstract class RSAAsymmetricKey implements AsymmetricKey {
|
|
// The parameters of this key
|
|
final BigInt? modulus;
|
|
final BigInt? exponent;
|
|
|
|
/// Create an asymmetric key for the given domain parameters
|
|
RSAAsymmetricKey(this.modulus, this.exponent);
|
|
|
|
/// Get modulus [n] = p·q
|
|
BigInt? get n => modulus;
|
|
}
|
|
|
|
/// Private keys in RSA
|
|
class RSAPrivateKey extends RSAAsymmetricKey implements PrivateKey {
|
|
// The secret prime factors of n
|
|
final BigInt? p;
|
|
final BigInt? q;
|
|
BigInt? _pubExp;
|
|
|
|
/// Create an RSA private key for the given parameters.
|
|
///
|
|
/// The optional public exponent parameter has been deprecated. It does not
|
|
/// have to be provided, because it can be calculated from the other values.
|
|
/// The optional parameter is retained for backward compatibility, but it
|
|
/// does not need to be provided.
|
|
|
|
RSAPrivateKey(BigInt modulus, BigInt privateExponent, this.p, this.q,
|
|
[@Deprecated('Public exponent is calculated from the other values')
|
|
BigInt? publicExponent])
|
|
: super(modulus, privateExponent) {
|
|
// Check RSA relationship between p, q and modulus hold true.
|
|
|
|
if (p! * q! != modulus) {
|
|
throw ArgumentError.value('modulus inconsistent with RSA p and q');
|
|
}
|
|
|
|
// Calculate the correct RSA public exponent
|
|
|
|
_pubExp = privateExponent.modInverse((p! - BigInt.one) * (q! - BigInt.one));
|
|
|
|
// If explicitly provided, the public exponent value must be correct.
|
|
if (publicExponent != null && publicExponent != _pubExp) {
|
|
throw ArgumentError(
|
|
'public exponent inconsistent with RSA private exponent, p and q');
|
|
}
|
|
}
|
|
|
|
/// Get private exponent [d] = e^-1
|
|
@Deprecated('Use privateExponent.')
|
|
BigInt? get d => exponent;
|
|
|
|
/// Get the private exponent (d)
|
|
BigInt? get privateExponent => exponent;
|
|
|
|
/// Get the public exponent (e)
|
|
BigInt? get publicExponent => _pubExp;
|
|
|
|
/// Get the public exponent (e)
|
|
@Deprecated('Use publicExponent.')
|
|
BigInt? get pubExponent => publicExponent;
|
|
|
|
@override
|
|
bool operator ==(Object other) {
|
|
if (other is RSAPrivateKey) {
|
|
return other.privateExponent == privateExponent &&
|
|
other.modulus == modulus;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
@override
|
|
int get hashCode => modulus.hashCode + privateExponent.hashCode;
|
|
}
|
|
|
|
/// Public keys in RSA
|
|
class RSAPublicKey extends RSAAsymmetricKey implements PublicKey {
|
|
/// Create an RSA public key for the given parameters.
|
|
RSAPublicKey(BigInt super.modulus, BigInt super.exponent);
|
|
|
|
/// Get public exponent [e]
|
|
@Deprecated('Use get publicExponent')
|
|
BigInt? get e => exponent;
|
|
|
|
/// Get the public exponent.
|
|
BigInt? get publicExponent => exponent;
|
|
|
|
@override
|
|
bool operator ==(Object other) {
|
|
if (other is RSAPublicKey) {
|
|
return (other.modulus == modulus) &&
|
|
(other.publicExponent == publicExponent);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
@override
|
|
int get hashCode => modulus.hashCode + publicExponent.hashCode;
|
|
}
|
|
|
|
/// A [Signature] created with RSA.
|
|
class RSASignature implements Signature {
|
|
final Uint8List bytes;
|
|
|
|
RSASignature(this.bytes);
|
|
|
|
@override
|
|
String toString() => bytes.toString();
|
|
@override
|
|
bool operator ==(Object other) {
|
|
if (other is! RSASignature) return false;
|
|
if (other.bytes.length != bytes.length) return false;
|
|
|
|
for (var i = 0; i < bytes.length; i++) {
|
|
if (bytes[i] != other.bytes[i]) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
@override
|
|
int get hashCode => bytes.hashCode;
|
|
}
|
|
|
|
/// A [Signature] created with PSS.
|
|
class PSSSignature implements Signature {
|
|
final Uint8List bytes;
|
|
|
|
PSSSignature(this.bytes);
|
|
|
|
@override
|
|
String toString() => bytes.toString();
|
|
|
|
@override
|
|
bool operator ==(Object other) {
|
|
if (other is! PSSSignature) return false;
|
|
if (other.bytes.length != bytes.length) return false;
|
|
|
|
for (var i = 0; i < bytes.length; i++) {
|
|
if (bytes[i] != other.bytes[i]) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
@override
|
|
int get hashCode => bytes.hashCode;
|
|
}
|