Skip to content
This repository has been archived by the owner on Dec 23, 2020. It is now read-only.

Commit

Permalink
add normalize option for ecdsa signatures
Browse files Browse the repository at this point in the history
Signed-off-by: Adam Crowder <[email protected]>
  • Loading branch information
cheeseandcereal committed Dec 20, 2019
1 parent a7cb803 commit 1d4984d
Show file tree
Hide file tree
Showing 7 changed files with 36 additions and 9 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ Changelog
* Fixed OAEPEncoding and PKCS1Encoding to use provided output offset value.
* Fixed RSA block length and offset checks in RSAEngine.processBlock.
* Fixed RSASigner.verifySignature to return false when signature is bad.
* Add optional `normalize` boolean on `generateSignature` and `normalize` function on `ECSignature` to convert an ecdsa signature to lower-s form

#### Version 1.0.2 (2019-11-15)

Expand Down
17 changes: 16 additions & 1 deletion lib/ecc/api.dart
Original file line number Diff line number Diff line change
Expand Up @@ -157,10 +157,25 @@ class ECPublicKey extends ECAsymmetricKey implements PublicKey {
/// A [Signature] created with ECC.
class ECSignature implements Signature {
final BigInt r;
final BigInt s;
BigInt s;

ECSignature(this.r, this.s);

/**
* 'normalize' this signature by converting its s to lower-s form if necessary
* This is required to validate this signature with some libraries such as libsecp256k1
* which enforce lower-s form for all signatures to combat ecdsa signature malleability
*
* Returns false if the signature was already normalized, or true if it changed
*/
bool normalize(ECDomainParameters curveParams) {
if (s.compareTo(curveParams.n >> 1) > 0) {
s = curveParams.n - s;
return true;
}
return false;
}

String toString() => "(${r.toString()},${s.toString()})";

bool operator ==(other) {
Expand Down
6 changes: 4 additions & 2 deletions lib/signers/ecdsa_signer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ class ECDSASigner implements Signer {
}
}

Signature generateSignature(Uint8List message) {
Signature generateSignature(Uint8List message, {bool normalize = false}) {
message = _hashMessageIfNeeded(message);

var n = _pvkey.parameters.n;
Expand Down Expand Up @@ -126,7 +126,9 @@ class ECDSASigner implements Signer {
s = (k.modInverse(n) * (e + (d * r))) % n;
} while (s == BigInt.zero);

return new ECSignature(r, s);
var signature = new ECSignature(r, s);
if (normalize) signature.normalize(_pvkey.parameters);
return signature;
}

bool verifySignature(Uint8List message, covariant ECSignature signature) {
Expand Down
2 changes: 1 addition & 1 deletion lib/signers/rsa_signer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ class RSASigner implements Signer {
_rsa.init(forSigning, params);
}

RSASignature generateSignature(Uint8List message) {
RSASignature generateSignature(Uint8List message, {bool normalize = false}) {
if (!_forSigning) {
throw new StateError(
"Signer was not initialised for signature generation");
Expand Down
2 changes: 1 addition & 1 deletion lib/src/api/signer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ abstract class Signer extends Algorithm {
void init(bool forSigning, CipherParameters params);

/// Sign the passed in [message] (usually the output of a hash function)
Signature generateSignature(Uint8List message);
Signature generateSignature(Uint8List message, {bool normalize = false});

/// Verify the [message] against the [signature].
bool verifySignature(Uint8List message, Signature signature);
Expand Down
9 changes: 9 additions & 0 deletions test/signers/ecdsa_signer_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,15 @@ void main() {
_newSignature("4087581495017442027693712553398765118791696551913571321320",
"4593990646726045634082084213208629584972116888758459298644"),
]);

runSignerTests(new Signer("SHA-1/DET-ECDSA"), signParams, verifyParams, [
"Lorem ipsum dolor sit amet, consectetur adipiscing elit ........",
_newSignature("6052012072724008730564193612572794050491696411960275629627",
"2161019278549597185578307509265728228343111084484752661213"),
"En un lugar de La Mancha, de cuyo nombre no quiero acordarme ...",
_newSignature("4087581495017442027693712553398765118791696551913571321320",
"1683111088660635129753705209967429428795077884424382985437"),
], normalize: true);
}

ECSignature _newSignature(String r, String s) =>
Expand Down
8 changes: 4 additions & 4 deletions test/test/signer_tests.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import "package:pointycastle/pointycastle.dart";
import "./src/helpers.dart";

void runSignerTests(Signer signer, CipherParameters signParams(),
CipherParameters verifyParams(), List messageSignaturePairs) {
CipherParameters verifyParams(), List messageSignaturePairs, {bool normalize = false}) {
group("${signer.algorithmName}:", () {
group("generateSignature:", () {
for (var i = 0; i < messageSignaturePairs.length; i += 2) {
Expand All @@ -20,7 +20,7 @@ void runSignerTests(Signer signer, CipherParameters signParams(),
test(
"${formatAsTruncated(message)}",
() => _runGenerateSignatureTest(
signer, signParams, message, signature));
signer, signParams, message, signature, normalize: normalize));
}
});

Expand All @@ -39,11 +39,11 @@ void runSignerTests(Signer signer, CipherParameters signParams(),
}

void _runGenerateSignatureTest(Signer signer, CipherParameters params(),
String message, Signature expectedSignature) {
String message, Signature expectedSignature, {bool normalize = false}) {
signer.reset();
signer.init(true, params());

var signature = signer.generateSignature(createUint8ListFromString(message));
var signature = signer.generateSignature(createUint8ListFromString(message), normalize: normalize);

expect(signature, expectedSignature);
}
Expand Down

0 comments on commit 1d4984d

Please sign in to comment.