Fix sometimes erroneous Ed25519 public key to X25519 public key conversion.

Added mass (x1000) testing of key conversion and shared secret calculations.

Fix incorrect proxy private key test that has expected result from previous
algorithm.

Added another test HTML/JS file.
This commit is contained in:
catbref 2019-05-25 19:18:01 +01:00
parent 1b4369e5e8
commit f3c588d90f
3 changed files with 70 additions and 1 deletions

View File

@ -71,6 +71,8 @@ public class BouncyCastle25519 {
int[] u = new int[X25519Field.SIZE];
X25519Field.mul(onePlusY, oneMinusYInverted, u);
X25519Field.normalize(u);
byte[] x25519PublicKey = new byte[X25519.SCALAR_SIZE];
X25519Field.encode(u, x25519PublicKey, 0);

View File

@ -64,6 +64,29 @@ public class CryptoTests extends Common {
assertTrue(account.verify(signature, message));
}
@Test
public void testMassEd25519ToX25519() {
// Lots of random tests just in case of leading sign bit issues
SecureRandom random = new SecureRandom();
for (int i = 0; i < 1000; ++i) {
byte[] ed25519PrivateKey = new byte[32];
random.nextBytes(ed25519PrivateKey);
PrivateKeyAccount account = new PrivateKeyAccount(null, ed25519PrivateKey);
byte[] x25519PrivateKey = BouncyCastle25519.toX25519PrivateKey(account.getPrivateKey());
X25519PrivateKeyParameters x25519PrivateKeyParams = new X25519PrivateKeyParameters(x25519PrivateKey, 0);
// Derive X25519 public key from X25519 private key
byte[] x25519PublicKeyFromPrivate = x25519PrivateKeyParams.generatePublicKey().getEncoded();
// Derive X25519 public key from Ed25519 public key
byte[] x25519PublicKeyFromEd25519 = BouncyCastle25519.toX25519PublicKey(account.getPublicKey());
assertEquals(String.format("Public keys do not match, from private key %s", Base58.encode(ed25519PrivateKey)), Base58.encode(x25519PublicKeyFromPrivate), Base58.encode(x25519PublicKeyFromEd25519));
}
}
@Test
public void testBCseed() {
final String privateKey58 = "A9MNsATgQgruBUjxy2rjWY36Yf19uRioKZbiLFT2P7c6";
@ -197,12 +220,34 @@ public class CryptoTests extends Common {
assertEquals("shared secrets do not match", Base58.encode(ourSharedSecret), Base58.encode(theirSharedSecret));
}
@Test
public void testMassRandomBCSharedSecrets() {
// Lots of random shared secret tests just in case of leading sign bit issues
SecureRandom random = new SecureRandom();
for (int i = 0; i < 1000; ++i) {
byte[] ourPrivateKey = new byte[32];
random.nextBytes(ourPrivateKey);
PrivateKeyAccount ourAccount = new PrivateKeyAccount(null, ourPrivateKey);
byte[] theirPrivateKey = new byte[32];
random.nextBytes(theirPrivateKey);
PrivateKeyAccount theirAccount = new PrivateKeyAccount(null, theirPrivateKey);
byte[] ourSharedSecret = calcBCSharedSecret(ourPrivateKey, theirAccount.getPublicKey());
byte[] theirSharedSecret = calcBCSharedSecret(theirPrivateKey, ourAccount.getPublicKey());
assertEquals("#" + i + " shared secrets do not match", Base58.encode(ourSharedSecret), Base58.encode(theirSharedSecret));
}
}
@Test
public void testProxyKeys() {
final byte[] ourPrivateKey = Base58.decode("A9MNsATgQgruBUjxy2rjWY36Yf19uRioKZbiLFT2P7c6");
final byte[] theirPublicKey = Base58.decode("C6wuddsBV3HzRrXUtezE7P5MoRXp5m3mEDokRDGZB6ry");
final String expectedProxyPrivateKey = "CwBXkJRRaGzWRvdE9vewVUbcYNSVrcTpunNWm8zidArZ";
final String expectedProxyPrivateKey = "6KszntmNuXmpUkzLfuttgMPeownctxrnyZUG9rErKJJx";
PrivateKeyAccount mintingAccount = new PrivateKeyAccount(null, ourPrivateKey);
byte[] proxyPrivateKey = mintingAccount.getProxyPrivateKey(theirPublicKey);

View File

@ -0,0 +1,22 @@
<!doctype html>
<html>
<head>
<script src="Base58.js"></script>
<script src="nacl_factory.js"></script>
<script>
nacl_factory.instantiate(function (nacl) {
var ed25519PrivateKey = Base58.decode('GQjr1enbi7R4tbRYAbrcwWRWjH9avuC3nRhdGB3pR2DF');
var ed25519KeyPair = nacl.crypto_sign_seed_keypair(ed25519PrivateKey);
var x25519KeyPair = nacl.crypto_box_keypair_from_sign_sk(ed25519KeyPair.signSk);
var x25519PublicKeyFromPrivate = x25519KeyPair.boxPk;
console.log("X25519 public key from private: " + Base58.encode(x25519PublicKeyFromPrivate));
var x25519PublicKeyFromEd25519 = nacl.crypto_box_pk_from_sign_pk(ed25519KeyPair.signPk);
console.log("X25519 public key from Ed25519: " + Base58.encode(x25519PublicKeyFromEd25519));
});
</script>
</head>
<body>
</body>
</html>