Search in sources :

Example 1 with Signature

use of io.nem.symbol.core.crypto.Signature in project nem2-sdk-java by nemtech.

the class Ed25519DsaSigner method sign.

@Override
@SuppressWarnings("squid:S00117")
public Signature sign(final byte[] data) {
    if (!this.getKeyPair().hasPrivateKey()) {
        throw new CryptoException("cannot sign without private key");
    }
    Hasher hasher32 = Hashes::sha512;
    Hasher hasher64 = Hashes::sha512;
    // Hash the private key to improve randomness.
    final byte[] hash = hasher32.hash(this.getKeyPair().getPrivateKey().getBytes());
    // r = H(hash_b,...,hash_2b-1, data) where b=256.
    final Ed25519EncodedFieldElement r = new Ed25519EncodedFieldElement(hasher64.hash(// only
    Arrays.copyOfRange(hash, 32, 64), // key hash
    data));
    // Reduce size of r since we are calculating mod group order anyway
    final Ed25519EncodedFieldElement rModQ = r.modQ();
    // R = rModQ * base point.
    final Ed25519GroupElement R = Ed25519Group.BASE_POINT.scalarMultiply(rModQ);
    final Ed25519EncodedGroupElement encodedR = R.encode();
    // S = (r + H(encodedR, encodedA, data) * a) mod group order where
    // encodedR and encodedA are the little endian encodings of the group element R
    // and the
    // public
    // key A and
    // a is the lower 32 bytes of hash after clamping.
    final Ed25519EncodedFieldElement h = new Ed25519EncodedFieldElement(hasher64.hash(encodedR.getRaw(), this.getKeyPair().getPublicKey().getBytes(), data));
    final Ed25519EncodedFieldElement hModQ = h.modQ();
    final Ed25519EncodedFieldElement encodedS = hModQ.multiplyAndAddModQ(Ed25519Utils.prepareForScalarMultiply(this.getKeyPair().getPrivateKey()), rModQ);
    // Signature is (encodedR, encodedS)
    final Signature signature = new Signature(encodedR.getRaw(), encodedS.getRaw());
    if (!this.isCanonicalSignature(signature)) {
        throw new CryptoException("Generated signature is not canonical");
    }
    return signature;
}
Also used : Hasher(io.nem.symbol.core.crypto.Hasher) Signature(io.nem.symbol.core.crypto.Signature) Ed25519EncodedFieldElement(io.nem.symbol.core.crypto.ed25519.arithmetic.Ed25519EncodedFieldElement) Ed25519GroupElement(io.nem.symbol.core.crypto.ed25519.arithmetic.Ed25519GroupElement) CryptoException(io.nem.symbol.core.crypto.CryptoException) Ed25519EncodedGroupElement(io.nem.symbol.core.crypto.ed25519.arithmetic.Ed25519EncodedGroupElement)

Example 2 with Signature

use of io.nem.symbol.core.crypto.Signature in project nem2-sdk-java by nemtech.

the class Ed25519DsaSignerTest method signReturnsExpectedSignature.

@Test
public void signReturnsExpectedSignature() {
    // Arrange:
    final CryptoEngine engine = this.getCryptoEngine();
    final KeyPair keyPair = KeyPair.random(engine);
    for (int i = 0; i < 20; i++) {
        final DsaSigner dsaSigner = this.getDsaSigner(keyPair);
        final byte[] input = RandomUtils.generateRandomBytes();
        // Act:
        final Signature signature1 = dsaSigner.sign(input);
        final Signature signature2 = MathUtils.sign(keyPair, input);
        // Assert:
        Assertions.assertEquals(signature1, signature2);
    }
}
Also used : KeyPair(io.nem.symbol.core.crypto.KeyPair) CryptoEngine(io.nem.symbol.core.crypto.CryptoEngine) DsaSigner(io.nem.symbol.core.crypto.DsaSigner) Signature(io.nem.symbol.core.crypto.Signature) DsaSignerTest(io.nem.symbol.core.crypto.DsaSignerTest) Test(org.junit.jupiter.api.Test)

Example 3 with Signature

use of io.nem.symbol.core.crypto.Signature in project nem2-sdk-java by nemtech.

the class Ed25519DsaSignerTest method makeCanonicalMakesNonCanonicalSignatureCanonical.

@Test
public void makeCanonicalMakesNonCanonicalSignatureCanonical() {
    // Arrange:
    final CryptoEngine engine = this.getCryptoEngine();
    final KeyPair kp = KeyPair.random(engine);
    final DsaSigner dsaSigner = this.getDsaSigner(kp);
    final byte[] input = RandomUtils.generateRandomBytes();
    // Act:
    final Signature signature = dsaSigner.sign(input);
    final BigInteger nonCanonicalS = engine.getCurve().getGroupOrder().add(signature.getS());
    final Signature nonCanonicalSignature = new Signature(signature.getR(), nonCanonicalS);
    Assertions.assertFalse(dsaSigner.isCanonicalSignature(nonCanonicalSignature));
    final Signature canonicalSignature = dsaSigner.makeSignatureCanonical(nonCanonicalSignature);
    // Assert:
    Assertions.assertTrue(dsaSigner.isCanonicalSignature(canonicalSignature));
}
Also used : KeyPair(io.nem.symbol.core.crypto.KeyPair) CryptoEngine(io.nem.symbol.core.crypto.CryptoEngine) DsaSigner(io.nem.symbol.core.crypto.DsaSigner) Signature(io.nem.symbol.core.crypto.Signature) BigInteger(java.math.BigInteger) DsaSignerTest(io.nem.symbol.core.crypto.DsaSignerTest) Test(org.junit.jupiter.api.Test)

Example 4 with Signature

use of io.nem.symbol.core.crypto.Signature in project nem2-sdk-java by nemtech.

the class Ed25519DsaSignerTest method replacingRWithGroupOrderPlusRInSignatureRuinsSignature.

@Test
public void replacingRWithGroupOrderPlusRInSignatureRuinsSignature() {
    // Arrange:
    final CryptoEngine engine = this.getCryptoEngine();
    final BigInteger groupOrder = engine.getCurve().getGroupOrder();
    final KeyPair kp = KeyPair.random(engine);
    final DsaSigner dsaSigner = this.getDsaSigner(kp);
    Signature signature;
    byte[] input;
    while (true) {
        input = RandomUtils.generateRandomBytes();
        signature = dsaSigner.sign(input);
        if (signature.getR().add(groupOrder).compareTo(BigInteger.ONE.shiftLeft(256)) < 0) {
            break;
        }
    }
    // Act:
    final Signature signature2 = new Signature(groupOrder.add(signature.getR()), signature.getS());
    // Assert:
    Assertions.assertFalse(dsaSigner.verify(input, signature2));
}
Also used : KeyPair(io.nem.symbol.core.crypto.KeyPair) CryptoEngine(io.nem.symbol.core.crypto.CryptoEngine) DsaSigner(io.nem.symbol.core.crypto.DsaSigner) Signature(io.nem.symbol.core.crypto.Signature) BigInteger(java.math.BigInteger) DsaSignerTest(io.nem.symbol.core.crypto.DsaSignerTest) Test(org.junit.jupiter.api.Test)

Example 5 with Signature

use of io.nem.symbol.core.crypto.Signature in project nem2-sdk-java by nemtech.

the class Ed25519DsaSignerTest method verifyReturnsFalseIfPublicKeyIsZeroArray.

@Test
public void verifyReturnsFalseIfPublicKeyIsZeroArray() {
    // Arrange:
    final CryptoEngine engine = this.getCryptoEngine();
    final KeyPair kp = KeyPair.random(engine);
    final DsaSigner dsaSigner = this.getDsaSigner(kp);
    final byte[] input = RandomUtils.generateRandomBytes();
    final Signature signature = dsaSigner.sign(input);
    final Ed25519DsaSigner dsaSignerWithZeroArrayPublicKey = Mockito.mock(Ed25519DsaSigner.class);
    final KeyPair keyPairWithZeroArrayPublicKey = Mockito.mock(KeyPair.class);
    Mockito.when(dsaSignerWithZeroArrayPublicKey.getKeyPair()).thenReturn(keyPairWithZeroArrayPublicKey);
    Mockito.when(keyPairWithZeroArrayPublicKey.getPublicKey()).thenReturn(new PublicKey(new byte[32]));
    Mockito.when(dsaSignerWithZeroArrayPublicKey.verify(input, signature)).thenCallRealMethod();
    Mockito.when(dsaSignerWithZeroArrayPublicKey.isCanonicalSignature(signature)).thenReturn(true);
    // Act:
    final boolean result = dsaSignerWithZeroArrayPublicKey.verify(input, signature);
    // Assert (getKeyPair() would be called more than once if it got beyond the
    // second check):
    Assertions.assertFalse(result);
    Mockito.verify(dsaSignerWithZeroArrayPublicKey, Mockito.times(1)).isCanonicalSignature(signature);
    Mockito.verify(dsaSignerWithZeroArrayPublicKey, Mockito.times(1)).getKeyPair();
}
Also used : KeyPair(io.nem.symbol.core.crypto.KeyPair) CryptoEngine(io.nem.symbol.core.crypto.CryptoEngine) PublicKey(io.nem.symbol.core.crypto.PublicKey) DsaSigner(io.nem.symbol.core.crypto.DsaSigner) Signature(io.nem.symbol.core.crypto.Signature) DsaSignerTest(io.nem.symbol.core.crypto.DsaSignerTest) Test(org.junit.jupiter.api.Test)

Aggregations

Signature (io.nem.symbol.core.crypto.Signature)11 CryptoEngine (io.nem.symbol.core.crypto.CryptoEngine)7 DsaSigner (io.nem.symbol.core.crypto.DsaSigner)7 DsaSignerTest (io.nem.symbol.core.crypto.DsaSignerTest)7 KeyPair (io.nem.symbol.core.crypto.KeyPair)7 Test (org.junit.jupiter.api.Test)7 BigInteger (java.math.BigInteger)4 Hasher (io.nem.symbol.core.crypto.Hasher)2 Ed25519EncodedFieldElement (io.nem.symbol.core.crypto.ed25519.arithmetic.Ed25519EncodedFieldElement)2 CryptoException (io.nem.symbol.core.crypto.CryptoException)1 PublicKey (io.nem.symbol.core.crypto.PublicKey)1 Ed25519EncodedGroupElement (io.nem.symbol.core.crypto.ed25519.arithmetic.Ed25519EncodedGroupElement)1 Ed25519GroupElement (io.nem.symbol.core.crypto.ed25519.arithmetic.Ed25519GroupElement)1