3
0
mirror of https://github.com/Qortal/altcoinj.git synced 2025-01-30 23:02:15 +00:00

Extract ECDSASignature.isCanonical() which checks for BIP62 low S value. Adds a test.

This commit is contained in:
Andreas Schildbach 2014-12-19 20:44:19 +01:00
parent 18c63a703f
commit 17071ce15c
2 changed files with 18 additions and 5 deletions

View File

@ -495,6 +495,14 @@ public class ECKey implements EncryptableItem, Serializable {
this.s = s;
}
/**
* Returns true if the S component is "low", that means it is below {@link ECKey#HALF_CURVE_ORDER}. See <a
* href="https://github.com/bitcoin/bips/blob/master/bip-0062.mediawiki#Low_S_values_in_signatures">BIP62</a>.
*/
public boolean isCanonical() {
return s.compareTo(HALF_CURVE_ORDER) <= 0;
}
/**
* Will automatically adjust the S component to be less than or equal to half the curve order, if necessary.
* This is required because for every signature (r,s) the signature (r, -s (mod N)) is a valid signature of
@ -503,7 +511,7 @@ public class ECKey implements EncryptableItem, Serializable {
* considered legal and the other will be banned.
*/
public ECDSASignature toCanonicalised() {
if (s.compareTo(HALF_CURVE_ORDER) > 0) {
if (!isCanonical()) {
// The order of the curve is the number of valid points that exist on that curve. If S is in the upper
// half of the number of valid points, then bring it back to the lower half. Otherwise, imagine that
// N = 10

View File

@ -17,6 +17,7 @@
package org.bitcoinj.core;
import org.bitcoinj.core.ECKey.ECDSASignature;
import org.bitcoinj.crypto.EncryptedData;
import org.bitcoinj.crypto.KeyCrypter;
import org.bitcoinj.crypto.KeyCrypterScrypt;
@ -96,11 +97,15 @@ public class ECKeyTest {
}
List<ECKey.ECDSASignature> sigs = Futures.allAsList(sigFutures).get();
for (ECKey.ECDSASignature signature : sigs) {
assertTrue(signature.s.compareTo(ECKey.HALF_CURVE_ORDER) <= 0);
assertTrue(signature.isCanonical());
}
final ECKey.ECDSASignature duplicate = new ECKey.ECDSASignature(sigs.get(0).r, sigs.get(0).s);
assertEquals(sigs.get(0), duplicate);
assertEquals(sigs.get(0).hashCode(), duplicate.hashCode());
final ECDSASignature first = sigs.get(0);
final ECKey.ECDSASignature duplicate = new ECKey.ECDSASignature(first.r, first.s);
assertEquals(first, duplicate);
assertEquals(first.hashCode(), duplicate.hashCode());
final ECKey.ECDSASignature highS = new ECKey.ECDSASignature(first.r, ECKey.CURVE.getN().subtract(first.s));
assertFalse(highS.isCanonical());
}
@Test