Skip to content

Commit

Permalink
Merge pull request #97 from /issues/85
Browse files Browse the repository at this point in the history
issues/85 - Implements support for key pair generation using seed for…
  • Loading branch information
cnorburn authored Apr 6, 2022
2 parents 09c70b9 + c5617b7 commit ae0b323
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,12 @@ public Algorithm getAlgorithm() {
return algorithm;
}

KeyPair generateKeyPair(final String algorithm, final String curve) {
KeyPair generateKeyPair(final String algorithm, final String curve, final byte[] seed) {
try {
final KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(algorithm, PROVIDER);
final ECGenParameterSpec ecGenParameterSpec = new ECGenParameterSpec(curve);
keyPairGenerator.initialize(ecGenParameterSpec, new SecureRandom());
final SecureRandom secureRandom = seed != null ? new SecureRandom(seed) : new SecureRandom();
keyPairGenerator.initialize(ecGenParameterSpec, secureRandom);
return keyPairGenerator.generateKeyPair();
} catch (Exception e) {
throw new SignatureException(e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ class Ed25519KeyPariBuilder extends AbstractKeyPairBuilder {
}

@Override
public KeyPair generateKeyPair() {
return generateKeyPair(ALGORITHM, ALGORITHM);
public KeyPair generateKeyPair(final byte[] seed) {
return generateKeyPair(ALGORITHM, ALGORITHM, seed);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

import com.casper.sdk.types.Algorithm;

import javax.annotation.Nullable;
import java.security.KeyPair;
import java.security.PublicKey;

Expand All @@ -13,10 +14,10 @@ public interface KeyPairBuilder {

/**
* Generates a new key pair
*
* @param seed the optional entropy source to be used when generating a key pair
* @return a new key pain
*/
KeyPair generateKeyPair();
KeyPair generateKeyPair(@Nullable final byte [] seed);

/**
* The algorithm of the signer
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,9 @@ public class Secp256k1KeyPairBuilder extends AbstractKeyPairBuilder {
super(Algorithm.SECP256K1);
}

public KeyPair generateKeyPair() {
return generateKeyPair(ALGORITHM, CURVE_NAME);
@Override
public KeyPair generateKeyPair(final byte[] seed) {
return generateKeyPair(ALGORITHM, CURVE_NAME, seed);
}

@Override
Expand Down
13 changes: 12 additions & 1 deletion src/main/java/com/casper/sdk/service/signing/SigningService.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,18 @@ public class SigningService {
* @return a new key pair of the specified algorithm
*/
public KeyPair generateKeyPair(final Algorithm algorithm) {
return getKeyPairBuilder(algorithm).generateKeyPair();
return getKeyPairBuilder(algorithm).generateKeyPair(null);
}

/**
* Generates a key pair for the specified algorithm.
*
* @param algorithm the algorithm of new key pair to generate
* @param seed the entropy source to be used when generating a key pair
* @return a new key pair of the specified algorithm
*/
public KeyPair generateKeyPair(final Algorithm algorithm, final byte[] seed) {
return getKeyPairBuilder(algorithm).generateKeyPair(seed);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import java.nio.charset.StandardCharsets;
import java.security.KeyPair;
import java.security.PrivateKey;
import java.security.SecureRandom;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.Is.is;
Expand Down Expand Up @@ -88,6 +89,25 @@ void generateEd25519KeyPair() {
assertThat(signingService.verifySignature(keyPair.getPublic(), message, signature), is(true));
}

@Test
void generateEd25519KeyPairFromSeed() {

final SecureRandom random = new SecureRandom();
byte[] seed = new byte[20];
random.nextBytes(seed);

final KeyPair keyPair = signingService.generateKeyPair(Algorithm.ED25519, seed);
assertThat(keyPair.getPublic(), is(notNullValue()));
assertThat(keyPair.getPrivate(), is(notNullValue()));

// the message
byte[] message = "Message to sign".getBytes(StandardCharsets.UTF_8);

byte[] signature = signingService.signWithPrivateKey(keyPair.getPrivate(), message);

assertThat(signingService.verifySignature(keyPair.getPublic(), message, signature), is(true));
}

@Test
@SuppressWarnings("ConstantConditions")
void loadSecp256k1KeyPair() throws Exception {
Expand Down Expand Up @@ -123,6 +143,32 @@ void generateSecp256k1KeyPair() {
assertThat(signingService.verifySignature(keyPair.getPublic(), message, signedMessage), is(true));
}


@Test
void generateSecp256k1KeyPairFromSeed() {

final SecureRandom random = new SecureRandom();
byte[] seed = new byte[20];
random.nextBytes(seed);

final byte[] message = {
(byte) 153, (byte) 144, (byte) 19, (byte) 83, (byte) 219, (byte) 161, (byte) 143, (byte) 137, (byte) 59,
(byte) 67, (byte) 187, (byte) 238, (byte) 65, (byte) 111, (byte) 80, (byte) 243, (byte) 142, (byte) 77,
(byte) 113, (byte) 46, (byte) 2, (byte) 166, (byte) 121, (byte) 118, (byte) 34, (byte) 205, (byte) 123,
(byte) 14, (byte) 215, (byte) 85, (byte) 234, (byte) 161
};

final KeyPair keyPair = signingService.generateKeyPair(Algorithm.SECP256K1, seed);

assertThat(keyPair, is(notNullValue()));
assertThat(keyPair.getPublic(), is(notNullValue()));
assertThat(keyPair.getPrivate(), is(notNullValue()));

final byte[] signedMessage = signingService.signWithPrivateKey(keyPair.getPrivate(), message);

assertThat(signingService.verifySignature(keyPair.getPublic(), message, signedMessage), is(true));
}

@Test
@SuppressWarnings("ConstantConditions")
void signWithSecp256k1PrivateKeyAndVerifySignature() throws Exception {
Expand Down

0 comments on commit ae0b323

Please sign in to comment.