|
1 | 1 | package com.casper.sdk.service; |
2 | 2 |
|
3 | 3 | import com.casper.sdk.exception.CasperInvalidStateException; |
| 4 | +import com.casper.sdk.exception.NoSuchTypeException; |
| 5 | +import com.casper.sdk.helper.CasperTransferHelper; |
4 | 6 | import com.casper.sdk.identifier.block.HashBlockIdentifier; |
5 | 7 | import com.casper.sdk.identifier.block.HeightBlockIdentifier; |
6 | 8 | import com.casper.sdk.identifier.global.GlobalStateIdentifier; |
|
9 | 11 | import com.casper.sdk.identifier.purse.PurseIdentifier; |
10 | 12 | import com.casper.sdk.model.balance.QueryBalanceData; |
11 | 13 | import com.casper.sdk.model.block.JsonBlockData; |
| 14 | +import com.casper.sdk.model.common.Ttl; |
| 15 | +import com.casper.sdk.model.deploy.Deploy; |
| 16 | +import com.casper.sdk.model.deploy.DeployData; |
| 17 | +import com.casper.sdk.model.deploy.DeployResult; |
12 | 18 | import com.casper.sdk.model.era.EraInfoData; |
13 | 19 | import com.casper.sdk.model.key.PublicKey; |
14 | 20 | import com.casper.sdk.model.status.ChainspecData; |
15 | 21 | import com.casper.sdk.model.status.StatusData; |
16 | | -import com.syntifi.crypto.key.AbstractPrivateKey; |
17 | | -import com.syntifi.crypto.key.Ed25519PrivateKey; |
18 | | -import org.junit.Ignore; |
| 22 | +import com.syntifi.crypto.key.*; |
| 23 | +import dev.oak3.sbs4j.exception.ValueSerializationException; |
19 | 24 | import org.junit.jupiter.api.Assertions; |
20 | 25 | import org.junit.jupiter.api.Disabled; |
21 | 26 | import org.junit.jupiter.api.Test; |
22 | 27 |
|
23 | 28 | import java.io.IOException; |
24 | 29 | import java.math.BigInteger; |
| 30 | +import java.net.URISyntaxException; |
25 | 31 | import java.net.URL; |
26 | 32 | import java.nio.file.Files; |
27 | 33 | import java.nio.file.Path; |
| 34 | +import java.nio.file.Paths; |
| 35 | +import java.security.GeneralSecurityException; |
| 36 | +import java.util.*; |
28 | 37 |
|
29 | 38 | import static org.junit.jupiter.api.Assertions.*; |
30 | 39 |
|
@@ -179,5 +188,86 @@ void getGlobalStateAndReadAsString() { |
179 | 188 | } |
180 | 189 | } |
181 | 190 |
|
| 191 | + /** |
| 192 | + * We're testing the 50% Secp problem here |
| 193 | + * When a Secp public key is generated from prime numbers, there's a 50% chance it will 65bit or 66bit |
| 194 | + * When it's 65% the long public key is padded with zero |
| 195 | + * This test uses a Secp private key that will generate a 65bit padded public key |
| 196 | + */ |
| 197 | + @Test |
| 198 | + void testDeployWithPaddedPublicKey() throws URISyntaxException, IOException, NoSuchTypeException, GeneralSecurityException, ValueSerializationException { |
| 199 | + |
| 200 | + DeployData deploy; |
| 201 | + |
| 202 | + //First fund the private-padded.pem account from the faucet account |
| 203 | + final Ed25519PrivateKey faucetPrivateKey = new Ed25519PrivateKey(); |
| 204 | + final URL faucetKey = getClass().getResource("/net-1/faucet/secret_key.pem"); |
| 205 | + assert faucetKey != null; |
| 206 | + faucetPrivateKey.readPrivateKey(faucetKey.getFile()); |
| 207 | + |
| 208 | + Secp256k1PrivateKey paddedPrivateKey = new Secp256k1PrivateKey(); |
| 209 | + String filePath = getResourcesKeyPath("secp256k1/private-padded.pem"); |
| 210 | + paddedPrivateKey.readPrivateKey(filePath); |
| 211 | + |
| 212 | + |
| 213 | + byte[] paddedPublicKeyFull = paddedPrivateKey.getKeyPair().getPublicKey().toByteArray(); |
| 214 | + assert paddedPublicKeyFull[0] == (byte) 0; |
| 215 | + |
| 216 | + DeployResult deployResult = doDeploy(faucetPrivateKey, paddedPrivateKey.derivePublicKey()); |
| 217 | + |
| 218 | + assert deployResult != null; |
| 219 | + |
| 220 | + //wait for deploy to be accepted |
| 221 | + do { |
| 222 | + deploy = casperServiceNctl.getDeploy(deployResult.getDeployHash()); |
| 223 | + } while (deploy.getDeploy().getApprovals() == null || deploy.getDeploy().getApprovals().size() <= 0); |
| 224 | + |
| 225 | + |
| 226 | + //Now transfer from private-padded.pem to another user |
| 227 | + Secp256k1PrivateKey toPrivateKey = new Secp256k1PrivateKey(); |
| 228 | + filePath = getResourcesKeyPath("secp256k1/secret_key.pem"); |
| 229 | + toPrivateKey.readPrivateKey(filePath); |
| 230 | + |
| 231 | + deployResult = doDeploy(paddedPrivateKey, toPrivateKey.derivePublicKey()); |
| 232 | + |
| 233 | + assert deployResult != null; |
| 234 | + |
| 235 | + //wait for deploy to be accepted |
| 236 | + do { |
| 237 | + deploy = casperServiceNctl.getDeploy(deployResult.getDeployHash()); |
| 238 | + } while (deploy.getDeploy().getApprovals() == null || deploy.getDeploy().getApprovals().size() <= 0); |
| 239 | + |
| 240 | + |
| 241 | + assert Arrays.equals(deploy.getDeploy().getApprovals().get(0).getSigner().getPubKey().getKey(), paddedPrivateKey.derivePublicKey().getKey()); |
| 242 | + |
| 243 | + //now verify signature |
| 244 | + |
| 245 | + Secp256k1PublicKey paddedPublicKey = (Secp256k1PublicKey) paddedPrivateKey.derivePublicKey(); |
| 246 | + |
| 247 | + assert paddedPublicKey.verify(deploy.getDeploy().getHash().getDigest(), deploy.getDeploy().getApprovals().get(0).getSignature().getKey()); |
| 248 | + |
| 249 | + } |
| 250 | + |
| 251 | + private DeployResult doDeploy(final AbstractPrivateKey sk, final AbstractPublicKey pk) throws NoSuchTypeException, GeneralSecurityException, ValueSerializationException { |
| 252 | + |
| 253 | + final Deploy deploy = CasperTransferHelper.buildTransferDeploy( |
| 254 | + sk, |
| 255 | + PublicKey.fromAbstractPublicKey(pk), |
| 256 | + BigInteger.valueOf(2500000000L), |
| 257 | + "casper-net-1", |
| 258 | + Math.abs(new Random().nextLong()), |
| 259 | + BigInteger.valueOf(100000000L), |
| 260 | + 1L, |
| 261 | + Ttl.builder().ttl("30m").build(), |
| 262 | + new Date(), |
| 263 | + new ArrayList<>()); |
| 264 | + |
| 265 | + return casperServiceNctl.putDeploy(deploy); |
| 266 | + } |
| 267 | + |
| 268 | + |
| 269 | + protected String getResourcesKeyPath(String filename) throws URISyntaxException { |
| 270 | + return Paths.get(Objects.requireNonNull(getClass().getClassLoader().getResource(filename)).toURI()).toString(); |
| 271 | + } |
182 | 272 |
|
183 | 273 | } |
0 commit comments