Skip to content

Commit 2b0366b

Browse files
committed
sync code from dev-vrf into dev
2 parents f0a2c7a + 512d3fe commit 2b0366b

File tree

8 files changed

+458
-0
lines changed

8 files changed

+458
-0
lines changed

sdk-core/src/main/java/org/fisco/bcos/sdk/model/CryptoType.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@
1616
package org.fisco.bcos.sdk.model;
1717

1818
public class CryptoType {
19+
// signature related crypto type(0-999)
1920
public static final int ECDSA_TYPE = 0;
2021
public static final int SM_TYPE = 1;
22+
23+
// vrf related crypto type(1000-1999)
24+
public static final int ED25519_VRF_TYPE = 1000;
2125
}
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
/**
2+
* Copyright 2014-2020 [fisco-dev]
3+
*
4+
* <p>Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
5+
* except in compliance with the License. You may obtain a copy of the License at
6+
*
7+
* <p>http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* <p>Unless required by applicable law or agreed to in writing, software distributed under the
10+
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
11+
* express or implied. See the License for the specific language governing permissions and
12+
* limitations under the License.
13+
*/
14+
package org.fisco.bcos.sdk.crypto.vrf;
15+
16+
import com.webank.wedpr.crypto.CryptoResult;
17+
import com.webank.wedpr.crypto.NativeInterface;
18+
import java.math.BigInteger;
19+
import org.fisco.bcos.sdk.crypto.keypair.CryptoKeyPair;
20+
import org.fisco.bcos.sdk.crypto.keypair.ECDSAKeyPair;
21+
import org.fisco.bcos.sdk.model.CryptoType;
22+
import org.fisco.bcos.sdk.utils.Numeric;
23+
24+
public class Curve25519VRF implements VRFInterface {
25+
private final ECDSAKeyPair keyPairGenerator = new ECDSAKeyPair();
26+
27+
@Override
28+
public VRFKeyPair createKeyPair() {
29+
// default use secp256k1 to create the private key
30+
CryptoKeyPair keyPair = keyPairGenerator.generateKeyPair();
31+
return new VRFKeyPair(CryptoType.ED25519_VRF_TYPE, keyPair.getHexPrivateKey());
32+
}
33+
34+
@Override
35+
public String generateVRFProof(String privateKey, String vrfInput) {
36+
CryptoResult result =
37+
NativeInterface.curve25519GenVRFProof(
38+
Numeric.getKeyNoPrefix(
39+
CryptoKeyPair.UNCOMPRESSED_PUBLICKEY_FLAG_STR,
40+
privateKey,
41+
CryptoKeyPair.PRIVATE_KEY_SIZE_IN_HEX),
42+
vrfInput);
43+
if (result.wedprErrorMessage != null && !result.wedprErrorMessage.isEmpty()) {
44+
throw new VRFException("generate VRF Proof failed: " + result.wedprErrorMessage);
45+
}
46+
return result.vrfProof;
47+
}
48+
49+
@Override
50+
public boolean verify(String publicKey, String vrfInput, String vrfProof) {
51+
CryptoResult result = NativeInterface.curve25519VRFVerify(publicKey, vrfInput, vrfProof);
52+
if (result.wedprErrorMessage != null && !result.wedprErrorMessage.isEmpty()) {
53+
throw new VRFException("verify VRF Proof failed: " + result.wedprErrorMessage);
54+
}
55+
return result.vrfVerifyResult;
56+
}
57+
58+
@Override
59+
public String getPublicKeyFromPrivateKey(String privateKey) {
60+
CryptoResult result =
61+
NativeInterface.curve25519VRFGetPubKeyFromPrivateKey(
62+
Numeric.getKeyNoPrefix(
63+
CryptoKeyPair.UNCOMPRESSED_PUBLICKEY_FLAG_STR,
64+
privateKey,
65+
CryptoKeyPair.PRIVATE_KEY_SIZE_IN_HEX));
66+
if (result.wedprErrorMessage != null && !result.wedprErrorMessage.isEmpty()) {
67+
throw new VRFException("get VRF Proof failed: " + result.wedprErrorMessage);
68+
}
69+
return result.vrfPublicKey;
70+
}
71+
72+
@Override
73+
public String vrfProofToHash(String vrfProof) {
74+
CryptoResult result = NativeInterface.curve25519VRFProofToHash(vrfProof);
75+
if (result.wedprErrorMessage != null && !result.wedprErrorMessage.isEmpty()) {
76+
throw new VRFException("convert VRF Proof to hash failed:" + result.wedprErrorMessage);
77+
}
78+
return result.vrfHash;
79+
}
80+
81+
@Override
82+
public BigInteger vrfProofToRandomValue(String vrfProof) {
83+
return new BigInteger(vrfProofToHash(vrfProof), 16);
84+
}
85+
86+
@Override
87+
public boolean isValidVRFPublicKey(String vrfPublicKey) {
88+
CryptoResult result = NativeInterface.curve25519IsValidVRFPubKey(vrfPublicKey);
89+
if (result.wedprErrorMessage != null && !result.wedprErrorMessage.isEmpty()) {
90+
throw new VRFException("invalid VRF public key:" + result.wedprErrorMessage);
91+
}
92+
return result.isValidVRFPublicKey;
93+
}
94+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/**
2+
* Copyright 2014-2020 [fisco-dev]
3+
*
4+
* <p>Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
5+
* except in compliance with the License. You may obtain a copy of the License at
6+
*
7+
* <p>http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* <p>Unless required by applicable law or agreed to in writing, software distributed under the
10+
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
11+
* express or implied. See the License for the specific language governing permissions and
12+
* limitations under the License.
13+
*/
14+
package org.fisco.bcos.sdk.crypto.vrf;
15+
16+
/** Exceptioned when calling vrf related functions. */
17+
public class VRFException extends RuntimeException {
18+
public VRFException(String message) {
19+
super(message);
20+
}
21+
22+
public VRFException(String message, Throwable cause) {
23+
super(message, cause);
24+
}
25+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/**
2+
* Copyright 2014-2020 [fisco-dev]
3+
*
4+
* <p>Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
5+
* except in compliance with the License. You may obtain a copy of the License at
6+
*
7+
* <p>http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* <p>Unless required by applicable law or agreed to in writing, software distributed under the
10+
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
11+
* express or implied. See the License for the specific language governing permissions and
12+
* limitations under the License.
13+
*/
14+
package org.fisco.bcos.sdk.crypto.vrf;
15+
16+
import java.math.BigInteger;
17+
18+
public interface VRFInterface {
19+
VRFKeyPair createKeyPair();
20+
21+
String generateVRFProof(String privateKey, String vrfInput);
22+
23+
boolean verify(String publicKey, String vrfInput, String vrfProof);
24+
25+
String getPublicKeyFromPrivateKey(String privateKey);
26+
27+
String vrfProofToHash(String vrfProof);
28+
29+
BigInteger vrfProofToRandomValue(String vrfProof);
30+
31+
boolean isValidVRFPublicKey(String vrfPublicKey);
32+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/**
2+
* Copyright 2014-2020 [fisco-dev]
3+
*
4+
* <p>Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
5+
* except in compliance with the License. You may obtain a copy of the License at
6+
*
7+
* <p>http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* <p>Unless required by applicable law or agreed to in writing, software distributed under the
10+
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
11+
* express or implied. See the License for the specific language governing permissions and
12+
* limitations under the License.
13+
*/
14+
package org.fisco.bcos.sdk.crypto.vrf;
15+
16+
import org.fisco.bcos.sdk.crypto.keypair.CryptoKeyPair;
17+
import org.fisco.bcos.sdk.model.CryptoType;
18+
import org.fisco.bcos.sdk.utils.Numeric;
19+
20+
public class VRFKeyPair {
21+
private String vrfPublicKey;
22+
private String vrfPrivateKey;
23+
private VRFInterface vrfInterface;
24+
25+
private VRFKeyPair() {}
26+
27+
public VRFKeyPair(String vrfPrivateKey, String vrfPublicKey) {
28+
this.vrfPrivateKey =
29+
Numeric.getKeyNoPrefix(
30+
CryptoKeyPair.UNCOMPRESSED_PUBLICKEY_FLAG_STR,
31+
vrfPrivateKey,
32+
CryptoKeyPair.PRIVATE_KEY_SIZE_IN_HEX);
33+
this.vrfPublicKey = vrfPublicKey;
34+
}
35+
36+
public VRFKeyPair(int vrfCryptoType, String vrfPrivateKey) {
37+
if (vrfCryptoType == CryptoType.ED25519_VRF_TYPE) {
38+
vrfInterface = new Curve25519VRF();
39+
} else {
40+
throw new VRFException(
41+
"Invalid cryptoType, only support CryptoType.ED25519_VRF_TYPE = "
42+
+ CryptoType.ED25519_VRF_TYPE
43+
+ " now!");
44+
}
45+
this.vrfPrivateKey =
46+
Numeric.getKeyNoPrefix(
47+
CryptoKeyPair.UNCOMPRESSED_PUBLICKEY_FLAG_STR,
48+
vrfPrivateKey,
49+
CryptoKeyPair.PRIVATE_KEY_SIZE_IN_HEX);
50+
this.vrfPublicKey = vrfInterface.getPublicKeyFromPrivateKey(vrfPrivateKey);
51+
}
52+
53+
public String getVrfPublicKey() {
54+
return vrfPublicKey;
55+
}
56+
57+
public void setVrfPublicKey(String vrfPublicKey) {
58+
this.vrfPublicKey = vrfPublicKey;
59+
}
60+
61+
public String getVrfPrivateKey() {
62+
return vrfPrivateKey;
63+
}
64+
65+
public void setVrfPrivateKey(String vrfPrivateKey) {
66+
this.vrfPrivateKey = vrfPrivateKey;
67+
}
68+
}
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
/**
2+
* Copyright 2014-2020 [fisco-dev]
3+
*
4+
* <p>Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
5+
* except in compliance with the License. You may obtain a copy of the License at
6+
*
7+
* <p>http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* <p>Unless required by applicable law or agreed to in writing, software distributed under the
10+
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
11+
* express or implied. See the License for the specific language governing permissions and
12+
* limitations under the License.
13+
*/
14+
package org.fisco.bcos.sdk.crypto;
15+
16+
import org.fisco.bcos.sdk.crypto.hash.Hash;
17+
import org.fisco.bcos.sdk.crypto.hash.Keccak256;
18+
import org.fisco.bcos.sdk.crypto.hash.SM3Hash;
19+
import org.fisco.bcos.sdk.crypto.keypair.CryptoKeyPair;
20+
import org.fisco.bcos.sdk.crypto.keypair.ECDSAKeyPair;
21+
import org.fisco.bcos.sdk.crypto.keypair.SM2KeyPair;
22+
import org.fisco.bcos.sdk.crypto.vrf.Curve25519VRF;
23+
import org.fisco.bcos.sdk.crypto.vrf.VRFInterface;
24+
import org.fisco.bcos.sdk.crypto.vrf.VRFKeyPair;
25+
import org.junit.Assert;
26+
import org.junit.Test;
27+
28+
public class Curve25519VRFTest {
29+
@Test
30+
public void testCurve25519VRF()
31+
{
32+
// the valid case
33+
VRFInterface vrfInterface = new Curve25519VRF();
34+
Hash sm3Hash = new SM3Hash();
35+
Hash keccak256Hash = new Keccak256();
36+
CryptoKeyPair ecdsaCryptoKeyPair = (new ECDSAKeyPair());
37+
CryptoKeyPair sm2CryptoKeyPair = (new SM2KeyPair());
38+
testCurve25519VRFProve(vrfInterface, ecdsaCryptoKeyPair.getHexPrivateKey(), keccak256Hash, new ECDSAKeyPair().getHexPrivateKey());
39+
testCurve25519VRFProve(vrfInterface, sm2CryptoKeyPair.getHexPrivateKey(), sm3Hash, new SM2KeyPair().getHexPrivateKey());
40+
41+
// generate the VRFKeyPair
42+
VRFKeyPair vrfKeyPair = vrfInterface.createKeyPair();
43+
//testCurve25519VRFProve(vrfInterface, vrfKeyPair.getVrfPrivateKey(), keccak256Hash, (vrfInterface.createKeyPair()).getVrfPrivateKey());
44+
testCurve25519VRFProve(vrfInterface, vrfKeyPair.getVrfPrivateKey(), sm3Hash, (vrfInterface.createKeyPair()).getVrfPrivateKey());
45+
}
46+
47+
public void testCurve25519VRFProve(VRFInterface vrfInterface, String privateKey, Hash hashImpl, String anotherPrivateKey)
48+
{
49+
for(int i = 0; i < 10; i++) {
50+
String input = "abcde" + String.valueOf(i);
51+
testCurve25519VRFProve(vrfInterface, privateKey, input, anotherPrivateKey);
52+
String hash = hashImpl.hash(input);
53+
testCurve25519VRFProve(vrfInterface, privateKey, hash, anotherPrivateKey);
54+
}
55+
}
56+
57+
public void testCurve25519VRFProve(VRFInterface vrfInterface, String privateKey, String vrfInput, String fakePrivateKey)
58+
{
59+
// valid case
60+
String publicKey = vrfInterface.getPublicKeyFromPrivateKey(privateKey);
61+
Assert.assertTrue(vrfInterface.isValidVRFPublicKey(publicKey));
62+
63+
String vrfProof = vrfInterface.generateVRFProof(privateKey, vrfInput);
64+
Assert.assertTrue(vrfInterface.verify(publicKey, vrfInput, vrfProof));
65+
66+
// invalid case
67+
// case1: invalid public key
68+
String InvalidPublicKey = "abc";
69+
Assert.assertTrue(vrfInterface.isValidVRFPublicKey(InvalidPublicKey) == false);
70+
Assert.assertTrue(vrfInterface.verify(InvalidPublicKey, vrfInput, vrfProof) == false);
71+
72+
// case2: inconsistent vrf message
73+
Assert.assertTrue(vrfInterface.verify(publicKey, vrfInput + "_wrong", vrfProof) == false);
74+
75+
// case3: fake private key
76+
String fakePublicKey = vrfInterface.getPublicKeyFromPrivateKey(fakePrivateKey);
77+
Assert.assertTrue(vrfInterface.isValidVRFPublicKey(fakePublicKey));
78+
Assert.assertTrue(vrfInterface.verify(fakePublicKey, vrfInput + "_wrong", vrfProof) == false);
79+
}
80+
}

0 commit comments

Comments
 (0)