Skip to content

Commit

Permalink
EthSecpArtifactSigner to use compressed identifier or public key
Browse files Browse the repository at this point in the history
  • Loading branch information
usmansaleem committed Oct 23, 2024
1 parent 20daaad commit 92108da
Show file tree
Hide file tree
Showing 12 changed files with 79 additions and 54 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ static void initV3Keystores() throws IOException, GeneralSecurityException, Ciph
publicKeys = new ArrayList<>();
for (int i = 0; i < 4; i++) {
final ECKeyPair ecKeyPair = Keys.createEcKeyPair();
final ECPublicKey ecPublicKey = EthPublicKeyUtils.createPublicKey(ecKeyPair.getPublicKey());
final ECPublicKey ecPublicKey =
EthPublicKeyUtils.createPublicKeyFromBigInt(ecKeyPair.getPublicKey());
final String publicKeyHex =
IdentifierUtils.normaliseIdentifier(EthPublicKeyUtils.toHexString(ecPublicKey));
publicKeys.add(publicKeyHex);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ private void createConfigurationFiles(final Set<Integer> opaqueDataIds, final Ke
private String getPublicKey(final String key) {
return normaliseIdentifier(
EthPublicKeyUtils.toHexString(
EthPublicKeyUtils.createPublicKey(
EthPublicKeyUtils.createPublicKeyFromBigInt(
Credentials.create(key).getEcKeyPair().getPublicKey())));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,8 @@ void verifySignature(final Bytes signature, final String publicKeyHex) {
final byte[] s = signature.slice(32, 32).toArray();
final byte[] v = signature.slice(64).toArray();
final BigInteger messagePublicKey = recoverPublicKey(new SignatureData(v, r, s));
assertThat(EthPublicKeyUtils.createPublicKey(messagePublicKey)).isEqualTo(expectedPublicKey);
assertThat(EthPublicKeyUtils.createPublicKeyFromBigInt(messagePublicKey))
.isEqualTo(expectedPublicKey);
}

private BigInteger recoverPublicKey(final SignatureData signature) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public ArtifactSigner generateECProxyKey(final String identifier)
final ECKeyPair ecKeyPair = Keys.createEcKeyPair(secureRandom);
final Path ecWalletFile = createECWalletFile(ecKeyPair, identifier);
LOG.debug("Created proxy EC wallet file {} for identifier: {}", ecWalletFile, identifier);
return new EthSecpArtifactSigner(new CredentialSigner(Credentials.create(ecKeyPair)));
return new EthSecpArtifactSigner(new CredentialSigner(Credentials.create(ecKeyPair)), true);
}

public ArtifactSigner generateBLSProxyKey(final String identifier) throws UncheckedIOException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,8 @@ public void ifAddressIsNotUnlockedExceptionIsThrownWithSigningNotUnlocked() {
public void signatureHasTheExpectedFormat() {
final Credentials cs =
Credentials.create("0x1618fc3e47aec7e70451256e033b9edb67f4c469258d8e2fbb105552f141ae41");
final ECPublicKey key = EthPublicKeyUtils.createPublicKey(cs.getEcKeyPair().getPublicKey());
final ECPublicKey key =
EthPublicKeyUtils.createPublicKeyFromBigInt(cs.getEcKeyPair().getPublicKey());
final String addr = Keys.getAddress(EthPublicKeyUtils.toHexString(key));

final BigInteger v = BigInteger.ONE;
Expand Down Expand Up @@ -169,7 +170,8 @@ public void returnsExpectedSignatureForEip1559Transaction() {
private String executeEthSignTransaction(final JsonObject params) {
final Credentials cs =
Credentials.create("0x1618fc3e47aec7e70451256e033b9edb67f4c469258d8e2fbb105552f141ae41");
final ECPublicKey key = EthPublicKeyUtils.createPublicKey(cs.getEcKeyPair().getPublicKey());
final ECPublicKey key =
EthPublicKeyUtils.createPublicKeyFromBigInt(cs.getEcKeyPair().getPublicKey());
final String addr = Keys.getAddress(EthPublicKeyUtils.toHexString(key));

doAnswer(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,23 @@

public class EthSecpArtifactSigner implements ArtifactSigner {
private final Signer signer;
private final boolean isCompressed;

public EthSecpArtifactSigner(final Signer signer) {
this.signer = signer;
this.isCompressed = false;
}

public EthSecpArtifactSigner(final Signer signer, final boolean isCompressed) {
this.signer = signer;
this.isCompressed = isCompressed;
}

@Override
public String getIdentifier() {
return IdentifierUtils.normaliseIdentifier(
EthPublicKeyUtils.toHexString(signer.getPublicKey()));
final String hexString =
EthPublicKeyUtils.getEncoded(signer.getPublicKey(), isCompressed, false).toHexString();
return IdentifierUtils.normaliseIdentifier(hexString);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ public class SecpV3KeystoresBulkLoader {

public static MappedResults<ArtifactSigner> loadV3KeystoresUsingPasswordFileOrDir(
final Path keystoresPath, final Path pwrdFileOrDirPath) {
return loadV3KeystoresUsingPasswordFileOrDir(keystoresPath, pwrdFileOrDirPath, false);
}

public static MappedResults<ArtifactSigner> loadV3KeystoresUsingPasswordFileOrDir(
final Path keystoresPath, final Path pwrdFileOrDirPath, final boolean isCompressed) {
if (!Files.exists(pwrdFileOrDirPath)) {
LOG.error("Password file or directory doesn't exist.");
return MappedResults.errorResult();
Expand Down Expand Up @@ -67,12 +72,12 @@ public static MappedResults<ArtifactSigner> loadV3KeystoresUsingPasswordFileOrDi
}

return keystoresFiles.parallelStream()
.map(keystoreFile -> createSecpArtifactSigner(keystoreFile, passwordReader))
.map(keystoreFile -> createSecpArtifactSigner(keystoreFile, passwordReader, isCompressed))
.reduce(MappedResults.newSetInstance(), MappedResults::merge);
}

private static MappedResults<ArtifactSigner> createSecpArtifactSigner(
final Path v3KeystorePath, final PasswordReader passwordReader) {
final Path v3KeystorePath, final PasswordReader passwordReader, final boolean isCompressed) {
try {
final String fileNameWithoutExt =
FilenameUtils.removeExtension(v3KeystorePath.getFileName().toString());
Expand All @@ -82,7 +87,7 @@ private static MappedResults<ArtifactSigner> createSecpArtifactSigner(
final Credentials credentials =
WalletUtils.loadCredentials(password, v3KeystorePath.toFile());
final EthSecpArtifactSigner artifactSigner =
new EthSecpArtifactSigner(new CredentialSigner(credentials));
new EthSecpArtifactSigner(new CredentialSigner(credentials), isCompressed);
return MappedResults.newInstance(Set.of(artifactSigner), 0);
} catch (final IOException | CipherException | RuntimeException e) {
LOG.error("Error loading v3 keystore {}", v3KeystorePath, e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,41 +77,44 @@ public Future<Void> load() {
if (!keystoreParameter.isEnabled()) {
return;
}
signers.forEach(
(identifier, __) -> {
final Path identifierPath =
keystoreParameter.getKeystoresPath().resolve(identifier);
if (identifierPath.toFile().canRead()
&& identifierPath.toFile().isDirectory()) {
final Path v4Dir = identifierPath.resolve("v4");

if (v4Dir.toFile().canRead() && v4Dir.toFile().isDirectory()) {
// load v4 proxy signers
final BlsKeystoreBulkLoader v4Loader = new BlsKeystoreBulkLoader();
final MappedResults<ArtifactSigner> blsSignersResult =
v4Loader.loadKeystoresUsingPasswordFile(
v4Dir, keystoreParameter.getKeystoresPasswordFile());
final Collection<ArtifactSigner> blsSigners =
blsSignersResult.getValues();
proxySigners
.computeIfAbsent(identifier, k -> new ArrayList<>())
.addAll(blsSigners);
}

final Path v3Dir = identifierPath.resolve("v3");
if (v3Dir.toFile().canRead() && v3Dir.toFile().isDirectory()) {
// load v3 proxy signers
final MappedResults<ArtifactSigner> secpSignersResults =
SecpV3KeystoresBulkLoader.loadV3KeystoresUsingPasswordFileOrDir(
v3Dir, keystoreParameter.getKeystoresPasswordFile());
final Collection<ArtifactSigner> secpSigners =
secpSignersResults.getValues();
proxySigners
.computeIfAbsent(identifier, k -> new ArrayList<>())
.addAll(secpSigners);
}
}
});

signers
.keySet()
.forEach(
identifier -> {
final Path identifierPath =
keystoreParameter.getKeystoresPath().resolve(identifier);
if (identifierPath.toFile().canRead()
&& identifierPath.toFile().isDirectory()) {
final Path v4Dir = identifierPath.resolve("v4");

if (v4Dir.toFile().canRead() && v4Dir.toFile().isDirectory()) {
// load v4 proxy signers
final BlsKeystoreBulkLoader v4Loader = new BlsKeystoreBulkLoader();
final MappedResults<ArtifactSigner> blsSignersResult =
v4Loader.loadKeystoresUsingPasswordFile(
v4Dir, keystoreParameter.getKeystoresPasswordFile());
final Collection<ArtifactSigner> blsSigners =
blsSignersResult.getValues();
proxySigners
.computeIfAbsent(identifier, k -> new ArrayList<>())
.addAll(blsSigners);
}

final Path v3Dir = identifierPath.resolve("v3");
if (v3Dir.toFile().canRead() && v3Dir.toFile().isDirectory()) {
// load v3 proxy signers (compressed pub key).
final MappedResults<ArtifactSigner> secpSignersResults =
SecpV3KeystoresBulkLoader.loadV3KeystoresUsingPasswordFileOrDir(
v3Dir, keystoreParameter.getKeystoresPasswordFile(), true);
final Collection<ArtifactSigner> secpSigners =
secpSignersResults.getValues();
proxySigners
.computeIfAbsent(identifier, k -> new ArrayList<>())
.addAll(secpSigners);
}
}
});
});

LOG.info("Total signers (keys) currently loaded in memory: {}", signers.size());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ private static ECPublicKey createPublicKeyFromPoint(final ECPoint point) {
* @return The created ECPublicKey
* @throws IllegalArgumentException if the input is invalid
*/
public static ECPublicKey createPublicKey(final BigInteger publicKeyValue) {
public static ECPublicKey createPublicKeyFromBigInt(final BigInteger publicKeyValue) {
if (publicKeyValue == null) {
throw new IllegalArgumentException("Public key value cannot be null");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ public class CredentialSigner implements Signer {

public CredentialSigner(final Credentials credentials, final boolean needToHash) {
this.credentials = credentials;
this.publicKey = EthPublicKeyUtils.createPublicKey(credentials.getEcKeyPair().getPublicKey());
this.publicKey =
EthPublicKeyUtils.createPublicKeyFromBigInt(credentials.getEcKeyPair().getPublicKey());
this.needToHash = needToHash;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,15 +143,15 @@ void proxySignersAreLoadedCorrectly() throws IOException {
assertThat(key1ProxyPublicKeys.get(KeyType.BLS))
.containsExactlyInAnyOrder(getPublicKeysArray(key1ProxyKeyPairs));
assertThat(key1ProxyPublicKeys.get(KeyType.SECP256K1))
.containsExactlyInAnyOrder(getSecpPublicKeysArray(key1SecpKeyPairs));
.containsExactlyInAnyOrder(getCompressedSecpPublicKeysArray(key1SecpKeyPairs));

final Map<KeyType, List<String>> key2ProxyPublicKeys =
signerProvider.getProxyIdentifiers(PUBLIC_KEY2);

assertThat(key2ProxyPublicKeys.get(KeyType.BLS))
.containsExactlyInAnyOrder(getPublicKeysArray(key2ProxyKeyPairs));
assertThat(key2ProxyPublicKeys.get(KeyType.SECP256K1))
.containsExactlyInAnyOrder(getSecpPublicKeysArray(key2SecpKeyPairs));
.containsExactlyInAnyOrder(getCompressedSecpPublicKeysArray(key2SecpKeyPairs));
}

@Test
Expand Down Expand Up @@ -223,12 +223,16 @@ private static String[] getPublicKeysArray(final List<BLSKeyPair> blsKeyPairs) {
.toArray(String[]::new);
}

private static String[] getSecpPublicKeysArray(final List<ECKeyPair> ecKeyPairs) {
private static String[] getCompressedSecpPublicKeysArray(final List<ECKeyPair> ecKeyPairs) {
// compressed public keys
return ecKeyPairs.stream()
.map(
keyPair ->
EthPublicKeyUtils.toHexString(
EthPublicKeyUtils.createPublicKey(keyPair.getPublicKey())))
EthPublicKeyUtils.getEncoded(
EthPublicKeyUtils.createPublicKeyFromBigInt(keyPair.getPublicKey()),
true,
false)
.toHexString())
.toList()
.toArray(String[]::new);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public void createsPublicKeyFromBytes() {
@Test
public void createsPublicKeyFromBigInteger() {
final BigInteger publicKey = Numeric.toBigInt(PUBLIC_KEY);
final ECPublicKey ecPublicKey = EthPublicKeyUtils.createPublicKey(publicKey);
final ECPublicKey ecPublicKey = EthPublicKeyUtils.createPublicKeyFromBigInt(publicKey);

final Bytes expectedPublicKeyBytes = Bytes.fromHexString(PUBLIC_KEY);
final ECPoint expectedEcPoint = createEcPoint(expectedPublicKeyBytes);
Expand Down

0 comments on commit 92108da

Please sign in to comment.