* develop: Modify license files, readme files, and other configurations change configure files and shell files change configure files Fix bugs in test case; # Conflicts: # README.md # source/crypto/crypto-framework/src/main/java/com/jd/blockchain/crypto/CryptoAlgorithm.java # source/crypto/crypto-framework/src/main/java/com/jd/blockchain/crypto/impl/AsymmtricCryptographyImpl.java # source/crypto/crypto-framework/src/main/java/com/jd/blockchain/crypto/impl/HashCryptographyImpl.java # source/crypto/crypto-framework/src/main/java/com/jd/blockchain/crypto/impl/jni/asymmetric/JNIED25519SignatureFunction.java # source/crypto/crypto-framework/src/main/java/com/jd/blockchain/crypto/impl/jni/hash/JNIRIPEMD160HashFunction.java # source/crypto/crypto-framework/src/main/java/com/jd/blockchain/crypto/impl/jni/hash/JNISHA256HashFunction.java # source/crypto/crypto-framework/src/test/java/test/com/jd/blockchain/crypto/asymmetric/AsymmtricCryptographyImplTest.java # source/crypto/crypto-framework/src/test/java/test/com/jd/blockchain/crypto/hash/HashCryptographyImplTest.java # source/crypto/crypto-framework/src/test/java/test/com/jd/blockchain/crypto/jniutils/JNIED25519UtilsTest.java # source/crypto/crypto-framework/src/test/java/test/com/jd/blockchain/crypto/jniutils/JNIMBSHA256UtilsTest.java # source/crypto/crypto-framework/src/test/java/test/com/jd/blockchain/crypto/jniutils/JNIRIPEMD160UtilsTest.java # source/crypto/crypto-framework/src/test/java/test/com/jd/blockchain/crypto/jniutils/JNISHA256UtilsTest.javatags/1.0.0
@@ -1,202 +1,225 @@ | |||
Apache License | |||
Version 2.0, January 2004 | |||
http://www.apache.org/licenses/ | |||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION | |||
1. Definitions. | |||
"License" shall mean the terms and conditions for use, reproduction, | |||
and distribution as defined by Sections 1 through 9 of this document. | |||
"Licensor" shall mean the copyright owner or entity authorized by | |||
the copyright owner that is granting the License. | |||
"Legal Entity" shall mean the union of the acting entity and all | |||
other entities that control, are controlled by, or are under common | |||
control with that entity. For the purposes of this definition, | |||
"control" means (i) the power, direct or indirect, to cause the | |||
direction or management of such entity, whether by contract or | |||
otherwise, or (ii) ownership of fifty percent (50%) or more of the | |||
outstanding shares, or (iii) beneficial ownership of such entity. | |||
"You" (or "Your") shall mean an individual or Legal Entity | |||
exercising permissions granted by this License. | |||
"Source" form shall mean the preferred form for making modifications, | |||
including but not limited to software source code, documentation | |||
source, and configuration files. | |||
"Object" form shall mean any form resulting from mechanical | |||
transformation or translation of a Source form, including but | |||
not limited to compiled object code, generated documentation, | |||
and conversions to other media types. | |||
"Work" shall mean the work of authorship, whether in Source or | |||
Object form, made available under the License, as indicated by a | |||
copyright notice that is included in or attached to the work | |||
(an example is provided in the Appendix below). | |||
"Derivative Works" shall mean any work, whether in Source or Object | |||
form, that is based on (or derived from) the Work and for which the | |||
editorial revisions, annotations, elaborations, or other modifications | |||
represent, as a whole, an original work of authorship. For the purposes | |||
of this License, Derivative Works shall not include works that remain | |||
separable from, or merely link (or bind by name) to the interfaces of, | |||
the Work and Derivative Works thereof. | |||
"Contribution" shall mean any work of authorship, including | |||
the original version of the Work and any modifications or additions | |||
to that Work or Derivative Works thereof, that is intentionally | |||
submitted to Licensor for inclusion in the Work by the copyright owner | |||
or by an individual or Legal Entity authorized to submit on behalf of | |||
the copyright owner. For the purposes of this definition, "submitted" | |||
means any form of electronic, verbal, or written communication sent | |||
to the Licensor or its representatives, including but not limited to | |||
communication on electronic mailing lists, source code control systems, | |||
and issue tracking systems that are managed by, or on behalf of, the | |||
Licensor for the purpose of discussing and improving the Work, but | |||
excluding communication that is conspicuously marked or otherwise | |||
designated in writing by the copyright owner as "Not a Contribution." | |||
"Contributor" shall mean Licensor and any individual or Legal Entity | |||
on behalf of whom a Contribution has been received by Licensor and | |||
subsequently incorporated within the Work. | |||
2. Grant of Copyright License. Subject to the terms and conditions of | |||
this License, each Contributor hereby grants to You a perpetual, | |||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable | |||
copyright license to reproduce, prepare Derivative Works of, | |||
publicly display, publicly perform, sublicense, and distribute the | |||
Work and such Derivative Works in Source or Object form. | |||
3. Grant of Patent License. Subject to the terms and conditions of | |||
this License, each Contributor hereby grants to You a perpetual, | |||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable | |||
(except as stated in this section) patent license to make, have made, | |||
use, offer to sell, sell, import, and otherwise transfer the Work, | |||
where such license applies only to those patent claims licensable | |||
by such Contributor that are necessarily infringed by their | |||
Contribution(s) alone or by combination of their Contribution(s) | |||
with the Work to which such Contribution(s) was submitted. If You | |||
institute patent litigation against any entity (including a | |||
cross-claim or counterclaim in a lawsuit) alleging that the Work | |||
or a Contribution incorporated within the Work constitutes direct | |||
or contributory patent infringement, then any patent licenses | |||
granted to You under this License for that Work shall terminate | |||
as of the date such litigation is filed. | |||
4. Redistribution. You may reproduce and distribute copies of the | |||
Work or Derivative Works thereof in any medium, with or without | |||
modifications, and in Source or Object form, provided that You | |||
meet the following conditions: | |||
(a) You must give any other recipients of the Work or | |||
Derivative Works a copy of this License; and | |||
(b) You must cause any modified files to carry prominent notices | |||
stating that You changed the files; and | |||
(c) You must retain, in the Source form of any Derivative Works | |||
that You distribute, all copyright, patent, trademark, and | |||
attribution notices from the Source form of the Work, | |||
excluding those notices that do not pertain to any part of | |||
the Derivative Works; and | |||
(d) If the Work includes a "NOTICE" text file as part of its | |||
distribution, then any Derivative Works that You distribute must | |||
include a readable copy of the attribution notices contained | |||
within such NOTICE file, excluding those notices that do not | |||
pertain to any part of the Derivative Works, in at least one | |||
of the following places: within a NOTICE text file distributed | |||
as part of the Derivative Works; within the Source form or | |||
documentation, if provided along with the Derivative Works; or, | |||
within a display generated by the Derivative Works, if and | |||
wherever such third-party notices normally appear. The contents | |||
of the NOTICE file are for informational purposes only and | |||
do not modify the License. You may add Your own attribution | |||
notices within Derivative Works that You distribute, alongside | |||
or as an addendum to the NOTICE text from the Work, provided | |||
that such additional attribution notices cannot be construed | |||
as modifying the License. | |||
You may add Your own copyright statement to Your modifications and | |||
may provide additional or different license terms and conditions | |||
for use, reproduction, or distribution of Your modifications, or | |||
for any such Derivative Works as a whole, provided Your use, | |||
reproduction, and distribution of the Work otherwise complies with | |||
the conditions stated in this License. | |||
5. Submission of Contributions. Unless You explicitly state otherwise, | |||
any Contribution intentionally submitted for inclusion in the Work | |||
by You to the Licensor shall be under the terms and conditions of | |||
this License, without any additional terms or conditions. | |||
Notwithstanding the above, nothing herein shall supersede or modify | |||
the terms of any separate license agreement you may have executed | |||
with Licensor regarding such Contributions. | |||
6. Trademarks. This License does not grant permission to use the trade | |||
names, trademarks, service marks, or product names of the Licensor, | |||
except as required for reasonable and customary use in describing the | |||
origin of the Work and reproducing the content of the NOTICE file. | |||
7. Disclaimer of Warranty. Unless required by applicable law or | |||
agreed to in writing, Licensor provides the Work (and each | |||
Contributor provides its Contributions) on an "AS IS" BASIS, | |||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or | |||
implied, including, without limitation, any warranties or conditions | |||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A | |||
PARTICULAR PURPOSE. You are solely responsible for determining the | |||
appropriateness of using or redistributing the Work and assume any | |||
risks associated with Your exercise of permissions under this License. | |||
8. Limitation of Liability. In no event and under no legal theory, | |||
whether in tort (including negligence), contract, or otherwise, | |||
unless required by applicable law (such as deliberate and grossly | |||
negligent acts) or agreed to in writing, shall any Contributor be | |||
liable to You for damages, including any direct, indirect, special, | |||
incidental, or consequential damages of any character arising as a | |||
result of this License or out of the use or inability to use the | |||
Work (including but not limited to damages for loss of goodwill, | |||
work stoppage, computer failure or malfunction, or any and all | |||
other commercial damages or losses), even if such Contributor | |||
has been advised of the possibility of such damages. | |||
9. Accepting Warranty or Additional Liability. While redistributing | |||
the Work or Derivative Works thereof, You may choose to offer, | |||
and charge a fee for, acceptance of support, warranty, indemnity, | |||
or other liability obligations and/or rights consistent with this | |||
License. However, in accepting such obligations, You may act only | |||
on Your own behalf and on Your sole responsibility, not on behalf | |||
of any other Contributor, and only if You agree to indemnify, | |||
defend, and hold each Contributor harmless for any liability | |||
incurred by, or claims asserted against, such Contributor by reason | |||
of your accepting any such warranty or additional liability. | |||
END OF TERMS AND CONDITIONS | |||
APPENDIX: How to apply the Apache License to your work. | |||
To apply the Apache License to your work, attach the following | |||
boilerplate notice, with the fields enclosed by brackets "[]" | |||
replaced with your own identifying information. (Don't include | |||
the brackets!) The text should be enclosed in the appropriate | |||
comment syntax for the file format. We also recommend that a | |||
file or class name and description of purpose be included on the | |||
same "printed page" as the copyright notice for easier | |||
identification within third-party archives. | |||
Copyright [yyyy] [name of copyright owner] | |||
Licensed under the Apache License, Version 2.0 (the "License"); | |||
you may not use this file except in compliance with the License. | |||
You may obtain a copy of the License at | |||
http://www.apache.org/licenses/LICENSE-2.0 | |||
Unless required by applicable law or agreed to in writing, software | |||
distributed under the License is distributed on an "AS IS" BASIS, | |||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
See the License for the specific language governing permissions and | |||
limitations under the License. | |||
Apache License | |||
Version 2.0, January 2004 | |||
http://www.apache.org/licenses/ | |||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION | |||
1. Definitions. | |||
"License" shall mean the terms and conditions for use, reproduction, | |||
and distribution as defined by Sections 1 through 9 of this document. | |||
"Licensor" shall mean the copyright owner or entity authorized by | |||
the copyright owner that is granting the License. | |||
"Legal Entity" shall mean the union of the acting entity and all | |||
other entities that control, are controlled by, or are under common | |||
control with that entity. For the purposes of this definition, | |||
"control" means (i) the power, direct or indirect, to cause the | |||
direction or management of such entity, whether by contract or | |||
otherwise, or (ii) ownership of fifty percent (50%) or more of the | |||
outstanding shares, or (iii) beneficial ownership of such entity. | |||
"You" (or "Your") shall mean an individual or Legal Entity | |||
exercising permissions granted by this License. | |||
"Source" form shall mean the preferred form for making modifications, | |||
including but not limited to software source code, documentation | |||
source, and configuration files. | |||
"Object" form shall mean any form resulting from mechanical | |||
transformation or translation of a Source form, including but | |||
not limited to compiled object code, generated documentation, | |||
and conversions to other media types. | |||
"Work" shall mean the work of authorship, whether in Source or | |||
Object form, made available under the License, as indicated by a | |||
copyright notice that is included in or attached to the work | |||
(an example is provided in the Appendix below). | |||
"Derivative Works" shall mean any work, whether in Source or Object | |||
form, that is based on (or derived from) the Work and for which the | |||
editorial revisions, annotations, elaborations, or other modifications | |||
represent, as a whole, an original work of authorship. For the purposes | |||
of this License, Derivative Works shall not include works that remain | |||
separable from, or merely link (or bind by name) to the interfaces of, | |||
the Work and Derivative Works thereof. | |||
"Contribution" shall mean any work of authorship, including | |||
the original version of the Work and any modifications or additions | |||
to that Work or Derivative Works thereof, that is intentionally | |||
submitted to Licensor for inclusion in the Work by the copyright owner | |||
or by an individual or Legal Entity authorized to submit on behalf of | |||
the copyright owner. For the purposes of this definition, "submitted" | |||
means any form of electronic, verbal, or written communication sent | |||
to the Licensor or its representatives, including but not limited to | |||
communication on electronic mailing lists, source code control systems, | |||
and issue tracking systems that are managed by, or on behalf of, the | |||
Licensor for the purpose of discussing and improving the Work, but | |||
excluding communication that is conspicuously marked or otherwise | |||
designated in writing by the copyright owner as "Not a Contribution." | |||
"Contributor" shall mean Licensor and any individual or Legal Entity | |||
on behalf of whom a Contribution has been received by Licensor and | |||
subsequently incorporated within the Work. | |||
2. Grant of Copyright License. Subject to the terms and conditions of | |||
this License, each Contributor hereby grants to You a perpetual, | |||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable | |||
copyright license to reproduce, prepare Derivative Works of, | |||
publicly display, publicly perform, sublicense, and distribute the | |||
Work and such Derivative Works in Source or Object form. | |||
3. Grant of Patent License. Subject to the terms and conditions of | |||
this License, each Contributor hereby grants to You a perpetual, | |||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable | |||
(except as stated in this section) patent license to make, have made, | |||
use, offer to sell, sell, import, and otherwise transfer the Work, | |||
where such license applies only to those patent claims licensable | |||
by such Contributor that are necessarily infringed by their | |||
Contribution(s) alone or by combination of their Contribution(s) | |||
with the Work to which such Contribution(s) was submitted. If You | |||
institute patent litigation against any entity (including a | |||
cross-claim or counterclaim in a lawsuit) alleging that the Work | |||
or a Contribution incorporated within the Work constitutes direct | |||
or contributory patent infringement, then any patent licenses | |||
granted to You under this License for that Work shall terminate | |||
as of the date such litigation is filed. | |||
4. Redistribution. You may reproduce and distribute copies of the | |||
Work or Derivative Works thereof in any medium, with or without | |||
modifications, and in Source or Object form, provided that You | |||
meet the following conditions: | |||
(a) You must give any other recipients of the Work or | |||
Derivative Works a copy of this License; and | |||
(b) You must cause any modified files to carry prominent notices | |||
stating that You changed the files; and | |||
(c) You must retain, in the Source form of any Derivative Works | |||
that You distribute, all copyright, patent, trademark, and | |||
attribution notices from the Source form of the Work, | |||
excluding those notices that do not pertain to any part of | |||
the Derivative Works; and | |||
(d) If the Work includes a "NOTICE" text file as part of its | |||
distribution, then any Derivative Works that You distribute must | |||
include a readable copy of the attribution notices contained | |||
within such NOTICE file, excluding those notices that do not | |||
pertain to any part of the Derivative Works, in at least one | |||
of the following places: within a NOTICE text file distributed | |||
as part of the Derivative Works; within the Source form or | |||
documentation, if provided along with the Derivative Works; or, | |||
within a display generated by the Derivative Works, if and | |||
wherever such third-party notices normally appear. The contents | |||
of the NOTICE file are for informational purposes only and | |||
do not modify the License. You may add Your own attribution | |||
notices within Derivative Works that You distribute, alongside | |||
or as an addendum to the NOTICE text from the Work, provided | |||
that such additional attribution notices cannot be construed | |||
as modifying the License. | |||
You may add Your own copyright statement to Your modifications and | |||
may provide additional or different license terms and conditions | |||
for use, reproduction, or distribution of Your modifications, or | |||
for any such Derivative Works as a whole, provided Your use, | |||
reproduction, and distribution of the Work otherwise complies with | |||
the conditions stated in this License. | |||
5. Submission of Contributions. Unless You explicitly state otherwise, | |||
any Contribution intentionally submitted for inclusion in the Work | |||
by You to the Licensor shall be under the terms and conditions of | |||
this License, without any additional terms or conditions. | |||
Notwithstanding the above, nothing herein shall supersede or modify | |||
the terms of any separate license agreement you may have executed | |||
with Licensor regarding such Contributions. | |||
6. Trademarks. This License does not grant permission to use the trade | |||
names, trademarks, service marks, or product names of the Licensor, | |||
except as required for reasonable and customary use in describing the | |||
origin of the Work and reproducing the content of the NOTICE file. | |||
7. Disclaimer of Warranty. Unless required by applicable law or | |||
agreed to in writing, Licensor provides the Work (and each | |||
Contributor provides its Contributions) on an "AS IS" BASIS, | |||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or | |||
implied, including, without limitation, any warranties or conditions | |||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A | |||
PARTICULAR PURPOSE. You are solely responsible for determining the | |||
appropriateness of using or redistributing the Work and assume any | |||
risks associated with Your exercise of permissions under this License. | |||
8. Limitation of Liability. In no event and under no legal theory, | |||
whether in tort (including negligence), contract, or otherwise, | |||
unless required by applicable law (such as deliberate and grossly | |||
negligent acts) or agreed to in writing, shall any Contributor be | |||
liable to You for damages, including any direct, indirect, special, | |||
incidental, or consequential damages of any character arising as a | |||
result of this License or out of the use or inability to use the | |||
Work (including but not limited to damages for loss of goodwill, | |||
work stoppage, computer failure or malfunction, or any and all | |||
other commercial damages or losses), even if such Contributor | |||
has been advised of the possibility of such damages. | |||
9. Accepting Warranty or Additional Liability. While redistributing | |||
the Work or Derivative Works thereof, You may choose to offer, | |||
and charge a fee for, acceptance of support, warranty, indemnity, | |||
or other liability obligations and/or rights consistent with this | |||
License. However, in accepting such obligations, You may act only | |||
on Your own behalf and on Your sole responsibility, not on behalf | |||
of any other Contributor, and only if You agree to indemnify, | |||
defend, and hold each Contributor harmless for any liability | |||
incurred by, or claims asserted against, such Contributor by reason | |||
of your accepting any such warranty or additional liability. | |||
END OF TERMS AND CONDITIONS | |||
APPENDIX: How to apply the Apache License to your work. | |||
To apply the Apache License to your work, attach the following | |||
boilerplate notice, with the fields enclosed by brackets "[]" | |||
replaced with your own identifying information. (Don't include | |||
the brackets!) The text should be enclosed in the appropriate | |||
comment syntax for the file format. We also recommend that a | |||
file or class name and description of purpose be included on the | |||
same "printed page" as the copyright notice for easier | |||
identification within third-party archives. | |||
Copyright 2019 Jingdong Digits Technology Holding Co., Ltd. | |||
Licensed under the Apache License, Version 2.0 (the "License"); | |||
you may not use this file except in compliance with the License. | |||
You may obtain a copy of the License at | |||
http://www.apache.org/licenses/LICENSE-2.0 | |||
Unless required by applicable law or agreed to in writing, software | |||
distributed under the License is distributed on an "AS IS" BASIS, | |||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
See the License for the specific language governing permissions and | |||
limitations under the License. | |||
------------------------------------------------------------------------------- | |||
The MIT License (MIT) | |||
Copyright (c) 2014 Hendrik Kunert | |||
Permission is hereby granted, free of charge, to any person obtaining a copy | |||
of this software and associated documentation files (the "Software"), to deal | |||
in the Software without restriction, including without limitation the rights | |||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |||
copies of the Software, and to permit persons to whom the Software is | |||
furnished to do so, subject to the following conditions: | |||
The above copyright notice and this permission notice shall be included in | |||
all copies or substantial portions of the Software. | |||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |||
THE SOFTWARE. |
@@ -1,5 +1,9 @@ | |||
[TOC] | |||
#JD区块链 0.5.0-SNAPSHOT | |||
#JD区块链 | |||
[![License](https://img.shields.io/badge/license-Apache%202-4EB1BA.svg)](https://www.apache.org/licenses/LICENSE-2.0.html) | |||
------------------------------------------------------------------------ | |||
### 版本修订历史 | |||
@@ -354,325 +358,266 @@ JD区块链的核心对象包括: | |||
## 五、编程接口 | |||
### 1. 服务连接 | |||
// 区块链共识域; | |||
String realm = "SUPPLY_CHAIN_ALLIANCE"; | |||
// 节点地址列表; | |||
String[] peerIPs = { "192.168.10.10", "192.168.10.11", "192.168.10.12", "192.168.10.13" }; | |||
// 客户端的认证账户; | |||
String clientAddress = "kkjsafieweqEkadsfaslkdslkae998232jojf=="; | |||
String privKey = "safefsd32q34vdsvs"; | |||
// 创建服务代理; | |||
BlockchainService service = BlockchainServiceFactory.createServiceProxy(realm, peerIPs, clientAddress, privKey); | |||
### 2. 账户注册 | |||
// 创建服务代理; | |||
BlockchainService service = BlockchainServiceFactory.createServiceProxy(realm, peerIPs, clientAddress, privKey); | |||
// 在本地定义注册账号的 TX; | |||
String sponsorAddress = "kFGeafiafEeqEkadsfaslkdslkae99ds66jf=="; | |||
String sponsorPrivKey = "privKkjwlkejflkjdsfoiajfij329323=="; | |||
TransactionTemplate txTemp = service.newTransaction(sponsorAddress); | |||
//-------------------------------------- | |||
// 区块链秘钥生成器;用于在客户端生成账户的公私钥和地址; | |||
BlockchainKeyGenerator generator = BlockchainKeyGenerator.getInstance(); | |||
BlockchainKeyPair bcKey1 = generator.generate(KeyType.ED25519); | |||
BlockchainKeyPair bcKey2 = generator.generate(KeyType.ED25519); | |||
String exchangeContractScript = "function(){}"; | |||
// 注册账户; | |||
txTemp.registerAccount() | |||
.register(bcKey1, AccountStateType.MAP, exchangeContractScript) | |||
.register(bcKey2, AccountStateType.OBJECT, null); | |||
//-------------------------------------- | |||
// TX 准备就绪; | |||
PreparedTransaction prepTx = txTemp.prepare(); | |||
// 使用私钥进行签名; | |||
prepTx.sign(sponsorAddress, sponsorPrivKey); | |||
// 提交交易; | |||
prepTx.commit(); | |||
### 3. 权限设置 | |||
// 创建服务代理; | |||
BlockchainService service = BlockchainServiceFactory.createServiceProxy(realm, peerIPs, clientAddress, privKey); | |||
// 在本地定义注册账号的 TX; | |||
String sponsorAddress = "kFGeafiafEeqEkadsfaslkdslkae99ds66jf=="; | |||
String sponsorPrivKey = "privKkjwlkejflkjdsfoiajfij329323=="; | |||
TransactionTemplate txTemp = service.newTransaction(sponsorAddress); | |||
//-------------------------------------- | |||
// 配置账户的权限; | |||
String walletAccount = "Kjfe8832hfa9jjjJJDkshrFjksjdlkfj93F=="; | |||
String user1 = "MMMEy902jkjjJJDkshreGeasdfassdfajjf=="; | |||
String user2 = "Kjfe8832hfa9jjjJJDkshrFjksjdlkfj93F=="; | |||
// 配置: | |||
// “状态数据的写入权限”的阈值为 100; | |||
// 需要 user1、user2 两个账户的联合签名才能写入; | |||
// 当前账户仅用于表示一个业务钱包,禁止自身的写入权限,只能由业务角色的账户才能操作; | |||
txTemp.configPrivilege(walletAccount) | |||
.setThreshhold(PrivilegeType.STATE_WRITE, 100) | |||
.enable(PrivilegeType.STATE_WRITE, user1, 50) | |||
.enable(PrivilegeType.STATE_WRITE, user2, 50) | |||
.disable(PrivilegeType.STATE_WRITE, walletAccount); | |||
//-------------------------------------- | |||
// TX 准备就绪; | |||
PreparedTransaction prepTx = txTemp.prepare(); | |||
// 使用私钥进行签名; | |||
prepTx.sign(sponsorAddress, sponsorPrivKey); | |||
// 提交交易; | |||
prepTx.commit(); | |||
```java | |||
//创建服务代理 | |||
public static BlockchainKeyPair CLIENT_CERT = BlockchainKeyGenerator.getInstance().generate(); | |||
final String GATEWAY_IP = "127.0.0.1"; | |||
final int GATEWAY_PORT = 80; | |||
final boolean SECURE = false; | |||
GatewayServiceFactory serviceFactory = GatewayServiceFactory.connect(GATEWAY_IP, GATEWAY_PORT, SECURE, | |||
CLIENT_CERT); | |||
// 创建服务代理; | |||
BlockchainService service = serviceFactory.getBlockchainService(); | |||
``` | |||
### 2. 用户注册 | |||
```java | |||
// 创建服务代理; | |||
BlockchainService service = serviceFactory.getBlockchainService(); | |||
// 在本地定义注册账号的 TX; | |||
TransactionTemplate txTemp = service.newTransaction(ledgerHash); | |||
SignatureFunction signatureFunction = asymmetricCryptography.getSignatureFunction(CryptoAlgorithm.ED25519); | |||
CryptoKeyPair cryptoKeyPair = signatureFunction.generateKeyPair(); | |||
BlockchainKeyPair user = new BlockchainKeyPair(cryptoKeyPair.getPubKey(), cryptoKeyPair.getPrivKey()); | |||
txTemp.users().register(user.getIdentity()); | |||
// TX 准备就绪; | |||
PreparedTransaction prepTx = txTemp.prepare(); | |||
// 使用私钥进行签名; | |||
CryptoKeyPair keyPair = getSponsorKey(); | |||
prepTx.sign(keyPair); | |||
// 提交交易; | |||
prepTx.commit(); | |||
``` | |||
### 3. 数据账户注册 | |||
```java | |||
// 创建服务代理; | |||
BlockchainService service = serviceFactory.getBlockchainService(); | |||
// 在本地定义注册账号的 TX; | |||
TransactionTemplate txTemp = service.newTransaction(ledgerHash); | |||
SignatureFunction signatureFunction = asymmetricCryptography.getSignatureFunction(CryptoAlgorithm.ED25519); | |||
CryptoKeyPair cryptoKeyPair = signatureFunction.generateKeyPair(); | |||
BlockchainKeyPair dataAccount = new BlockchainKeyPair(cryptoKeyPair.getPubKey(), cryptoKeyPair.getPrivKey()); | |||
txTemp.dataAccounts().register(dataAccount.getIdentity()); | |||
// TX 准备就绪; | |||
PreparedTransaction prepTx = txTemp.prepare(); | |||
// 使用私钥进行签名; | |||
CryptoKeyPair keyPair = getSponsorKey(); | |||
prepTx.sign(keyPair); | |||
// 提交交易; | |||
prepTx.commit(); | |||
``` | |||
### 4. 写入数据 | |||
// 创建服务代理; | |||
BlockchainService service = BlockchainServiceFactory.createServiceProxy(realm, peerIPs, clientAddress, privKey); | |||
// 在本地定义注册账号的 TX; | |||
String sponsorAddress = "kFGeafiafEeqEkadsfaslkdslkae99ds66jf=="; | |||
String sponsorPrivKey = "privKkjwlkejflkjdsfoiajfij329323=="; | |||
TransactionTemplate txTemp = service.newTransaction(sponsorAddress); | |||
// -------------------------------------- | |||
// 将商品信息写入到指定的账户中; | |||
// 对象将被序列化为 JSON 形式存储,并基于 JSON 结构建立查询索引; | |||
String commodityDataAccount = "GGhhreGeasdfasfUUfehf9932lkae99ds66jf=="; | |||
Commodity commodity1 = new Commodity(); | |||
Commodity commodity2 = new Commodity(); | |||
txTemp.updateObjects(commodityDataAccount) | |||
.insert(commodity1.getCode(), commodity1) | |||
.update(commodity2.getCode(), commodity2, true); | |||
// 在钱包账户以 KEY “RMB-ASSET” 表示一种数字资产,通过在一个 TX | |||
// 对两个账户的同一个资产数值分别增加和减少,实现转账的功能; | |||
String walletAccount1 = "MMMEy902jkjjJJDkshreGeasdfassdfajjf=="; | |||
String walletAccount2 = "Kjfe8832hfa9jjjJJDkshrFjksjdlkfj93F=="; | |||
txTemp.updateMap(walletAccount1).decreaseInt("RMB-ASSET", 1000); | |||
txTemp.updateMap(walletAccount2).increaseInt("RMB-ASSET", 1000); | |||
// -------------------------------------- | |||
// TX 准备就绪; | |||
PreparedTransaction prepTx = txTemp.prepare(); | |||
String txHash = prepTx.getHash(); | |||
// 使用私钥进行签名; | |||
prepTx.sign(sponsorAddress, sponsorPrivKey); | |||
// 提交交易; | |||
prepTx.commit(); | |||
```java | |||
// 创建服务代理; | |||
BlockchainService service = serviceFactory.getBlockchainService(); | |||
HashDigest ledgerHash = getLedgerHash(); | |||
// 在本地定义注册账号的 TX; | |||
TransactionTemplate txTemp = service.newTransaction(ledgerHash); | |||
// -------------------------------------- | |||
// 将商品信息写入到指定的账户中; | |||
// 对象将被序列化为 JSON 形式存储,并基于 JSON 结构建立查询索引; | |||
String commodityDataAccount = "GGhhreGeasdfasfUUfehf9932lkae99ds66jf=="; | |||
Commodity commodity1 = new Commodity(); | |||
txTemp.dataAccount(commodityDataAccount).set("ASSET_CODE", commodity1.getCode().getBytes(), -1); | |||
// TX 准备就绪; | |||
PreparedTransaction prepTx = txTemp.prepare(); | |||
String txHash = ByteArray.toBase64(prepTx.getHash().toBytes()); | |||
// 使用私钥进行签名; | |||
CryptoKeyPair keyPair = getSponsorKey(); | |||
prepTx.sign(keyPair); | |||
// 提交交易; | |||
prepTx.commit(); | |||
``` | |||
### 5. 查询数据 | |||
// 创建服务代理; | |||
BlockchainService service = BlockchainServiceFactory.createServiceProxy(realm, peerIPs, clientAddress, privKey); | |||
// 查询区块信息; | |||
// 区块高度; | |||
long ledgerNumber = service.getLedgerNumber(); | |||
// 最新区块; | |||
Block latestBlock = service.getBlock(ledgerNumber); | |||
// 区块中的交易的数量; | |||
int txCount = latestBlock.getTxCount(); | |||
// 获取交易列表; | |||
Transaction[] txList = service.getTransactions(ledgerNumber, 0, 100); | |||
// 根据交易的 hash 获得交易;注:客户端生成 PrepareTransaction 时得到交易hash; | |||
String txHash = "iikjeqke98321rjoijsdfa"; | |||
Transaction tx = service.getTransaction(txHash); | |||
// 获取数据; | |||
String commerceAccount = "GGhhreGeasdfasfUUfehf9932lkae99ds66jf=="; | |||
Set<String> objKeys = ArrayUtils.asSet(new String[] { "x001", "x002" }); | |||
PayloadMap payloadData = service.getPayload(commerceAccount, objKeys); | |||
AccountStateType payloadType = payloadData.getPayloadType(); | |||
long payloadVersion = payloadData.getPayloadVersion(); | |||
boolean exist = service.containPayload(commerceAccount, "x003"); | |||
// 按条件查询; | |||
// 1、从保存会员信息的账户地址查询; | |||
String condition = "female = true AND age > 18 AND address.city = 'beijing'"; | |||
String memberInfoAccountAddress = "kkf2io39823jfIjfiIRWKQj30203fx=="; | |||
PayloadMap memberInfo = service.queryObject(memberInfoAccountAddress, condition); | |||
// 2、从保存会员信息的账户地址查询; | |||
Map<String, PayloadMap> memberInfoWithAccounts = service.queryObject(condition); | |||
### 6. 合约调用 | |||
// 创建服务代理; | |||
BlockchainService service = BlockchainServiceFactory.createServiceProxy(realm, peerIPs, clientAddress, privKey); | |||
// 发起交易; | |||
String sponsorAddress = "kFGeafiafEeqEkadsfaslkdslkae99ds66jf=="; | |||
String sponsorPrivKey = "privKkjwlkejflkjdsfoiajfij329323=="; | |||
TransactionTemplate txTemp = service.newTransaction(sponsorAddress); | |||
// -------------------------------------- | |||
// 一个贸易账户,贸易结算后的利润将通过一个合约账户来执行利润分配; | |||
// 合约账户被设置为通用的账户,不具备对贸易结算账户的直接权限; | |||
// 只有当前交易发起人具备对贸易账户的直接权限,当交易发起人对交易进行签名之后,权限被间接传递给合约账户; | |||
String commerceAccount = "GGhhreGeasdfasfUUfehf9932lkae99ds66jf=="; | |||
// 处理利润分成的通用业务逻辑的合约账户; | |||
String profitDistributionContract = "AAdfe4346fHhefe34fwf343kaeER4678RT=="; | |||
//收益人账户; | |||
String receiptorAccount1 = "MMMEy902jkjjJJDkshreGeasdfassdfajjf=="; | |||
String receiptorAccount2 = "Kjfe8832hfa9jjjJJDkshrFjksjdlkfj93F=="; | |||
//资产编码; | |||
String assetKey = "RMB-ASSET"; | |||
//此次待分配利润; | |||
long profit = 1000000; | |||
//备注信息; | |||
Remark remark = new Remark(); | |||
String remarkJSON = SerializeUtils.serializeToJSON(remark); | |||
// 合约代码的参数表; | |||
String[] args = { commerceAccount, assetKey, profit+"", receiptorAccount1, receiptorAccount2, remarkJSON }; | |||
// 调用合约代码的分配操作; | |||
txTemp.executeScript(commerceAccount) | |||
.invoke("DISTRIBUTE", args); | |||
// -------------------------------------- | |||
// TX 准备就绪; | |||
PreparedTransaction prepTx = txTemp.prepare(); | |||
String txHash = prepTx.getHash(); | |||
> 注:详细的查询可参考模块sdk-samples中SDK_GateWay_Query_Test_相关测试用例 | |||
```java | |||
// 创建服务代理; | |||
BlockchainService service = serviceFactory.getBlockchainService(); | |||
// 查询区块信息; | |||
// 区块高度; | |||
long ledgerNumber = service.getLedger(LEDGER_HASH).getLatestBlockHeight(); | |||
// 最新区块; | |||
LedgerBlock latestBlock = service.getBlock(LEDGER_HASH, ledgerNumber); | |||
// 区块中的交易的数量; | |||
long txCount = service.getTransactionCount(LEDGER_HASH, latestBlock.getHash()); | |||
// 获取交易列表; | |||
LedgerTransaction[] txList = service.getTransactions(LEDGER_HASH, ledgerNumber, 0, 100); | |||
// 遍历交易列表 | |||
for (LedgerTransaction ledgerTransaction : txList) { | |||
TransactionContent txContent = ledgerTransaction.getTransactionContent(); | |||
Operation[] operations = txContent.getOperations(); | |||
if (operations != null && operations.length > 0) { | |||
for (Operation operation : operations) { | |||
operation = ClientOperationUtil.read(operation); | |||
// 操作类型:数据账户注册操作 | |||
if (operation instanceof DataAccountRegisterOperation) { | |||
DataAccountRegisterOperation daro = (DataAccountRegisterOperation) operation; | |||
BlockchainIdentity blockchainIdentity = daro.getAccountID(); | |||
} | |||
// 操作类型:用户注册操作 | |||
else if (operation instanceof UserRegisterOperation) { | |||
UserRegisterOperation uro = (UserRegisterOperation) operation; | |||
BlockchainIdentity blockchainIdentity = uro.getUserID(); | |||
} | |||
// 操作类型:账本注册操作 | |||
else if (operation instanceof LedgerInitOperation) { | |||
LedgerInitOperation ledgerInitOperation = (LedgerInitOperation)operation; | |||
LedgerInitSetting ledgerInitSetting = ledgerInitOperation.getInitSetting(); | |||
ParticipantNode[] participantNodes = ledgerInitSetting.getConsensusParticipants(); | |||
} | |||
// 操作类型:合约发布操作 | |||
else if (operation instanceof ContractCodeDeployOperation) { | |||
ContractCodeDeployOperation ccdo = (ContractCodeDeployOperation) operation; | |||
BlockchainIdentity blockchainIdentity = ccdo.getContractID(); | |||
} | |||
// 操作类型:合约执行操作 | |||
else if (operation instanceof ContractEventSendOperation) { | |||
ContractEventSendOperation ceso = (ContractEventSendOperation) operation; | |||
} | |||
// 操作类型:KV存储操作 | |||
else if (operation instanceof DataAccountKVSetOperation) { | |||
DataAccountKVSetOperation.KVWriteEntry[] kvWriteEntries = | |||
((DataAccountKVSetOperation) operation).getWriteSet(); | |||
if (kvWriteEntries != null && kvWriteEntries.length > 0) { | |||
for (DataAccountKVSetOperation.KVWriteEntry kvWriteEntry : kvWriteEntries) { | |||
BytesValue bytesValue = kvWriteEntry.getValue(); | |||
DataType dataType = bytesValue.getType(); | |||
Object showVal = ClientOperationUtil.readValueByBytesValue(bytesValue); | |||
System.out.println("writeSet.key=" + kvWriteEntry.getKey()); | |||
System.out.println("writeSet.value=" + showVal); | |||
System.out.println("writeSet.type=" + dataType); | |||
System.out.println("writeSet.version=" + kvWriteEntry.getExpectedVersion()); | |||
} | |||
} | |||
} | |||
} | |||
} | |||
} | |||
// 根据交易的 hash 获得交易;注:客户端生成 PrepareTransaction 时得到交易hash; | |||
HashDigest txHash = txList[0].getTransactionContent().getHash(); | |||
Transaction tx = service.getTransactionByContentHash(LEDGER_HASH, txHash); | |||
// 获取数据; | |||
String commerceAccount = "GGhhreGeasdfasfUUfehf9932lkae99ds66jf=="; | |||
String[] objKeys = new String[] { "x001", "x002" }; | |||
KVDataEntry[] kvData = service.getDataEntries(LEDGER_HASH, commerceAccount, objKeys); | |||
long payloadVersion = kvData[0].getVersion(); | |||
// 获取数据账户下所有的KV列表 | |||
KVDataEntry[] kvData = service.getDataEntries(ledgerHash, commerceAccount, 0, 100); | |||
if (kvData != null && kvData.length > 0) { | |||
for (KVDataEntry kvDatum : kvData) { | |||
System.out.println("kvData.key=" + kvDatum.getKey()); | |||
System.out.println("kvData.version=" + kvDatum.getVersion()); | |||
System.out.println("kvData.type=" + kvDatum.getType()); | |||
System.out.println("kvData.value=" + kvDatum.getValue()); | |||
} | |||
} | |||
``` | |||
### 6. 合约发布 | |||
```java | |||
// 创建服务代理; | |||
BlockchainService service = serviceFactory.getBlockchainService(); | |||
// 在本地定义TX模板 | |||
TransactionTemplate txTemp = service.newTransaction(ledgerHash); | |||
// 合约内容读取 | |||
byte[] contractBytes = FileUtils.readBytes(new File(CONTRACT_FILE)); | |||
// 生成用户 | |||
BlockchainIdentityData blockchainIdentity = new BlockchainIdentityData(getSponsorKey().getPubKey()); | |||
// 发布合约 | |||
txTemp.contracts().deploy(blockchainIdentity, contractBytes); | |||
// TX 准备就绪; | |||
PreparedTransaction prepTx = txTemp.prepare(); | |||
// 使用私钥进行签名; | |||
CryptoKeyPair keyPair = getSponsorKey(); | |||
prepTx.sign(keyPair); | |||
// 提交交易; | |||
TransactionResponse transactionResponse = prepTx.commit(); | |||
assertTrue(transactionResponse.isSuccess()); | |||
// 打印合约地址 | |||
System.out.println(blockchainIdentity.getAddress().toBase58()); | |||
``` | |||
### 7. 合约执行 | |||
```java | |||
// 创建服务代理; | |||
BlockchainService service = serviceFactory.getBlockchainService(); | |||
// 在本地定义TX模板 | |||
TransactionTemplate txTemp = service.newTransaction(ledgerHash); | |||
// 合约地址 | |||
String contractAddressBase58 = ""; | |||
// Event | |||
String event = ""; | |||
// 使用私钥进行签名; | |||
prepTx.sign(sponsorAddress, sponsorPrivKey); | |||
// args(注意参数的格式) | |||
byte[] args = "20##30##abc".getBytes(); | |||
// 提交交易; | |||
prepTx.commit(); | |||
### 7. 事件监听 | |||
// 创建服务代理; | |||
BlockchainService service = BlockchainServiceFactory.createServiceProxy(realm, peerIPs, clientAddress, privKey); | |||
//监听账户变动; | |||
String walletAccount = "MMMEy902jkjjJJDkshreGeasdfassdfajjf=="; | |||
service.addBlockchainEventListener(BlockchainEventType.PAYLOAD_UPDATED.CODE, null, walletAccount, new BlockchainEventListener() { | |||
@Override | |||
public void onEvent(BlockchainEventMessage eventMessage, BlockchainEventHandle eventHandle) { | |||
//钱包余额; | |||
PayloadMap balancePayload = service.getPayload(walletAccount, "RMB-ASSET"); | |||
Long balance =(Long) balancePayload.get("RMB-ASSET"); | |||
if (balance != null) { | |||
//notify balance change; | |||
}else{ | |||
//wallet is empty and isn't listened any more; | |||
eventHandle.cancel(); | |||
} | |||
} | |||
}); | |||
//销毁服务代理; | |||
service.dispose(); | |||
### 8. 合约开发 | |||
/** | |||
* 示例:一个“资产管理”智能合约的实现; | |||
* | |||
* 注: 1、实现 EventProcessingAwire 接口以便合约实例在运行时可以从上下文获得合约生命周期事件的通知; 2、实现 | |||
* AssetContract 接口定义的合约方法; | |||
* | |||
* @author huanghaiquan | |||
* | |||
*/ | |||
public class AssetContractImpl implements EventProcessingAwire, AssetContract { | |||
// 资产管理账户的地址; | |||
private static final String ASSET_ADDRESS = "2njZBNbFQcmKd385DxVejwSjy4driRzf9Pk"; | |||
// 保存资产总数的键; | |||
private static final String KEY_TOTAL = "TOTAL"; | |||
// 合约事件上下文; | |||
private ContractEventContext eventContext; | |||
/** | |||
* ------------------- 定义可以由外部用户通过提交“交易”触发的调用方法 ------------------ | |||
*/ | |||
@Override | |||
public void issue(long amount, String assetHolderAddress) { | |||
checkAllOwnersAgreementPermission(); | |||
// 新发行的资产数量; | |||
if (amount < 0) { | |||
throw new ContractError("The amount is negative!"); | |||
} | |||
if (amount == 0) { | |||
return; | |||
} | |||
// 校验持有者账户的有效性; | |||
BlockchainAccount holderAccount = eventContext.getLedger().getAccount(currentLedgerHash(), assetHolderAddress); | |||
if (holderAccount == null) { | |||
throw new ContractError("The holder is not exist!"); | |||
} | |||
// 查询当前值; | |||
Set<String> keys = new HashSet<>(); | |||
keys.add(KEY_TOTAL); | |||
keys.add(assetHolderAddress); | |||
StateMap currStates = eventContext.getLedger().getStates(currentLedgerHash(), ASSET_ADDRESS, keys); | |||
// 计算资产的发行总数; | |||
StateEntry currTotal = currStates.get(KEY_TOTAL); | |||
StateEntry newTotal = currTotal.newLong(currTotal.longValue() + amount); | |||
// 分配到持有者账户; | |||
StateEntry holderAmount = currStates.get(assetHolderAddress); | |||
StateEntry newHodlerAmount = holderAmount.newLong(holderAmount.longValue() + amount); | |||
// 把数据的更改写入到账本; | |||
SimpleStateMap newStates = new SimpleStateMap(currStates.getAccount(), currStates.getAccountVersion(), | |||
currStates.getStateVersion()); | |||
newStates.setValue(newTotal); | |||
newStates.setValue(newHodlerAmount); | |||
eventContext.getLedger().updateState(ASSET_ADDRESS).setStates(currStates); | |||
} | |||
@Override | |||
public void transfer(String fromAddress, String toAddress, long amount) { | |||
if (amount < 0) { | |||
throw new ContractError("The amount is negative!"); | |||
} | |||
if (amount == 0) { | |||
return; | |||
} | |||
//校验“转出账户”是否已签名; | |||
checkSignerPermission(fromAddress); | |||
// 查询现有的余额; | |||
Set<String> keys = new HashSet<>(); | |||
keys.add(fromAddress); | |||
keys.add(toAddress); | |||
StateMap origBalances = eventContext.getLedger().getStates(currentLedgerHash(), ASSET_ADDRESS, keys); | |||
StateEntry fromBalance = origBalances.get(fromAddress); | |||
StateEntry toBalance = origBalances.get(toAddress); | |||
//检查是否余额不足; | |||
if ((fromBalance.longValue() - amount) < 0) { | |||
throw new ContractError("Insufficient balance!"); | |||
} | |||
// 把数据的更改写入到账本; | |||
SimpleStateMap newBalances = new SimpleStateMap(origBalances.getAccount(), origBalances.getAccountVersion(), | |||
origBalances.getStateVersion()); | |||
StateEntry newFromBalance = fromBalance.newLong(fromBalance.longValue() - amount); | |||
StateEntry newToBalance = toBalance.newLong(toBalance.longValue() + amount); | |||
newBalances.setValue(newFromBalance); | |||
newBalances.setValue(newToBalance); | |||
eventContext.getLedger().updateState(ASSET_ADDRESS).setStates(newBalances); | |||
} | |||
} | |||
// 提交合约执行代码 | |||
txTemp.contractEvents().send(contractAddressBase58, event, args); | |||
// TX 准备就绪; | |||
PreparedTransaction prepTx = txTemp.prepare(); | |||
// 生成私钥并使用私钥进行签名; | |||
CryptoKeyPair keyPair = getSponsorKey(); | |||
prepTx.sign(keyPair); | |||
// 提交交易; | |||
TransactionResponse transactionResponse = prepTx.commit(); | |||
assertTrue(transactionResponse.isSuccess()); | |||
``` |
@@ -0,0 +1,223 @@ | |||
package com.jd.blockchain.crypto.impl; | |||
import com.jd.blockchain.crypto.Ciphertext; | |||
import com.jd.blockchain.crypto.CryptoAlgorithm; | |||
import com.jd.blockchain.crypto.asymmetric.AsymmetricCryptography; | |||
import com.jd.blockchain.crypto.asymmetric.AsymmetricEncryptionFunction; | |||
import com.jd.blockchain.crypto.asymmetric.CryptoKeyPair; | |||
import com.jd.blockchain.crypto.asymmetric.PrivKey; | |||
import com.jd.blockchain.crypto.asymmetric.PubKey; | |||
import com.jd.blockchain.crypto.asymmetric.SignatureDigest; | |||
import com.jd.blockchain.crypto.asymmetric.SignatureFunction; | |||
import com.jd.blockchain.crypto.impl.def.asymmetric.ED25519SignatureFunction; | |||
import com.jd.blockchain.crypto.impl.sm.asymmetric.SM2CryptoFunction; | |||
public class AsymmtricCryptographyImpl implements AsymmetricCryptography { | |||
private static final SignatureFunction ED25519_SIGF = new ED25519SignatureFunction(); | |||
private static final SignatureFunction SM2_SIGF = new SM2CryptoFunction(); | |||
// private static final SignatureFunction JNIED25519_SIGF = new JNIED25519SignatureFunction(); | |||
private static final AsymmetricEncryptionFunction SM2_ENCF = new SM2CryptoFunction(); | |||
/** | |||
* 封装了非对称密码算法对应的密钥生成算法 | |||
*/ | |||
@Override | |||
public CryptoKeyPair generateKeyPair(CryptoAlgorithm algorithm) { | |||
//判断算法是签名算法还是非对称加密算法,并根据算法生成密钥对,否则抛出异常 | |||
if (algorithm.isSignable() && algorithm.isAsymmetric()){ | |||
return getSignatureFunction(algorithm).generateKeyPair(); | |||
} | |||
else if (algorithm.isEncryptable() && algorithm.isAsymmetric()){ | |||
return getAsymmetricEncryptionFunction(algorithm).generateKeyPair(); | |||
} | |||
else throw new IllegalArgumentException("The specified algorithm is not signature or asymmetric encryption algorithm!"); | |||
} | |||
@Override | |||
public SignatureFunction getSignatureFunction(CryptoAlgorithm algorithm) { | |||
//遍历签名算法,如果满足,则返回实例 | |||
switch (algorithm) { | |||
case ED25519: | |||
return ED25519_SIGF; | |||
case SM2: | |||
return SM2_SIGF; | |||
// case JNIED25519: | |||
// return JNIED25519_SIGF; | |||
default: | |||
break; | |||
} | |||
throw new IllegalArgumentException("The specified algorithm is not signature algorithm!"); | |||
} | |||
@Override | |||
public boolean verify(byte[] digestBytes, byte[] pubKeyBytes, byte[] data) { | |||
//得到SignatureDigest类型的签名摘要,并得到算法标识 | |||
SignatureDigest signatureDigest = resolveSignatureDigest(digestBytes); | |||
CryptoAlgorithm algorithm = signatureDigest.getAlgorithm(); | |||
PubKey pubKey = resolvePubKey(pubKeyBytes); | |||
//验证两个输入中算法标识一致,否则抛出异常 | |||
if (algorithm != signatureDigest.getAlgorithm()) | |||
throw new IllegalArgumentException("Digest's algorithm and key's are not matching!"); | |||
//根据算法标识,调用对应算法实例来验证签名摘要 | |||
return getSignatureFunction(algorithm).verify(signatureDigest,pubKey,data); | |||
} | |||
@Override | |||
public AsymmetricEncryptionFunction getAsymmetricEncryptionFunction(CryptoAlgorithm algorithm) { | |||
//遍历非对称加密算法,如果满足,则返回实例 | |||
switch (algorithm) { | |||
case SM2: | |||
return SM2_ENCF; | |||
default: | |||
break; | |||
} | |||
throw new IllegalArgumentException("The specified algorithm is not asymmetric encryption algorithm!"); | |||
} | |||
@Override | |||
public byte[] decrypt(byte[] privKeyBytes, byte[] ciphertextBytes) { | |||
//分别得到PrivKey和Ciphertext类型的密钥和密文,以及privKey对应的算法 | |||
PrivKey privKey = resolvePrivKey(privKeyBytes); | |||
Ciphertext ciphertext = resolveCiphertext(ciphertextBytes); | |||
CryptoAlgorithm algorithm = privKey.getAlgorithm(); | |||
//验证两个输入中算法标识一致,否则抛出异常 | |||
if (algorithm != ciphertext.getAlgorithm()) | |||
throw new IllegalArgumentException("Ciphertext's algorithm and key's are not matching!"); | |||
//根据算法标识,调用对应算法实例来计算返回明文 | |||
return getAsymmetricEncryptionFunction(algorithm).decrypt(privKey,ciphertext); | |||
} | |||
@Override | |||
public Ciphertext resolveCiphertext(byte[] ciphertextBytes) { | |||
Ciphertext ciphertext = tryResolveCiphertext(ciphertextBytes); | |||
if (ciphertext == null) | |||
throw new IllegalArgumentException("This ciphertextBytes cannot be resolved!"); | |||
else return ciphertext; | |||
} | |||
@Override | |||
public Ciphertext tryResolveCiphertext(byte[] ciphertextBytes) { | |||
//遍历非对称加密算法,如果满足,则返回解析结果 | |||
if (SM2_ENCF.supportCiphertext(ciphertextBytes)){ | |||
return SM2_ENCF.resolveCiphertext(ciphertextBytes); | |||
} | |||
//否则返回null | |||
return null; | |||
} | |||
@Override | |||
public SignatureDigest resolveSignatureDigest(byte[] digestBytes) { | |||
SignatureDigest signatureDigest = tryResolveSignatureDigest(digestBytes); | |||
if (signatureDigest == null) | |||
throw new IllegalArgumentException("This digestBytes cannot be resolved!"); | |||
else return signatureDigest; | |||
} | |||
@Override | |||
public SignatureDigest tryResolveSignatureDigest(byte[] digestBytes) { | |||
//遍历签名算法,如果满足,则返回解析结果 | |||
if (ED25519_SIGF.supportDigest(digestBytes)){ | |||
return ED25519_SIGF.resolveDigest(digestBytes); | |||
} | |||
if (SM2_SIGF.supportDigest(digestBytes)){ | |||
return SM2_SIGF.resolveDigest(digestBytes); | |||
} | |||
// if (JNIED25519_SIGF.supportDigest(digestBytes)){ | |||
// return JNIED25519_SIGF.resolveDigest(digestBytes); | |||
// } | |||
//否则返回null | |||
return null; | |||
} | |||
@Override | |||
public byte[] retrievePubKeyBytes(byte[] privKeyBytes) { | |||
byte[] pubKeyBytes = tryRetrievePubKeyBytes(privKeyBytes); | |||
if (pubKeyBytes == null) | |||
throw new IllegalArgumentException("The specified algorithm in privKeyBytes is not signature or asymmetric encryption algorithm!"); | |||
else return pubKeyBytes; | |||
} | |||
@Override | |||
public byte[] tryRetrievePubKeyBytes(byte[] privKeyBytes) { | |||
//解析私钥获得算法标识 | |||
CryptoAlgorithm algorithm = resolvePrivKey(privKeyBytes).getAlgorithm(); | |||
//判断算法是签名算法还是非对称加密算法,并根据算法生成密钥对,否则抛出异常 | |||
if (algorithm.isSignable() && algorithm.isAsymmetric()){ | |||
return getSignatureFunction(algorithm).retrievePubKeyBytes(privKeyBytes); | |||
} | |||
else if (algorithm.isEncryptable() && algorithm.isAsymmetric()){ | |||
return getAsymmetricEncryptionFunction(algorithm).retrievePubKeyBytes(privKeyBytes); | |||
} | |||
//否则返回null | |||
return null; | |||
} | |||
@Override | |||
public PubKey resolvePubKey(byte[] pubKeyBytes) { | |||
PubKey pubKey = tryResolvePubKey(pubKeyBytes); | |||
if (pubKey == null) | |||
throw new IllegalArgumentException("This pubKeyBytes cannot be resolved!"); | |||
else return pubKey; | |||
} | |||
@Override | |||
public PubKey tryResolvePubKey(byte[] pubKeyBytes) { | |||
//遍历签名算法,如果满足,则返回解析结果 | |||
if (ED25519_SIGF.supportPubKey(pubKeyBytes)){ | |||
return ED25519_SIGF.resolvePubKey(pubKeyBytes); | |||
} | |||
if (SM2_SIGF.supportPubKey(pubKeyBytes)){ | |||
return SM2_SIGF.resolvePubKey(pubKeyBytes); | |||
} | |||
// if (JNIED25519_SIGF.supportPubKey(pubKeyBytes)){ | |||
// return JNIED25519_SIGF.resolvePubKey(pubKeyBytes); | |||
// } | |||
//遍历非对称加密算法,如果满足,则返回解析结果 | |||
if (SM2_ENCF.supportPubKey(pubKeyBytes)){ | |||
return SM2_ENCF.resolvePubKey(pubKeyBytes); | |||
} | |||
//否则返回null | |||
return null; | |||
} | |||
@Override | |||
public PrivKey resolvePrivKey(byte[] privKeyBytes) { | |||
PrivKey privKey = tryResolvePrivKey(privKeyBytes); | |||
if (privKey == null) | |||
throw new IllegalArgumentException("This privKeyBytes cannot be resolved!"); | |||
else return privKey; | |||
} | |||
@Override | |||
public PrivKey tryResolvePrivKey(byte[] privKeyBytes) { | |||
//遍历签名算法,如果满足,则返回解析结果 | |||
if (ED25519_SIGF.supportPrivKey(privKeyBytes)){ | |||
return ED25519_SIGF.resolvePrivKey(privKeyBytes); | |||
} | |||
if (SM2_SIGF.supportPrivKey(privKeyBytes)){ | |||
return SM2_SIGF.resolvePrivKey(privKeyBytes); | |||
} | |||
// if (JNIED25519_SIGF.supportPrivKey(privKeyBytes)){ | |||
// return JNIED25519_SIGF.resolvePrivKey(privKeyBytes); | |||
// } | |||
//遍历非对称加密算法,如果满足,则返回解析结果 | |||
if (SM2_ENCF.supportPrivKey(privKeyBytes)){ | |||
return SM2_ENCF.resolvePrivKey(privKeyBytes); | |||
} | |||
//否则返回null | |||
return null; | |||
} | |||
} |
@@ -0,0 +1,82 @@ | |||
package com.jd.blockchain.crypto.impl; | |||
import com.jd.blockchain.crypto.CryptoAlgorithm; | |||
import com.jd.blockchain.crypto.hash.HashCryptography; | |||
import com.jd.blockchain.crypto.hash.HashDigest; | |||
import com.jd.blockchain.crypto.hash.HashFunction; | |||
import com.jd.blockchain.crypto.impl.def.hash.RIPEMD160HashFunction; | |||
import com.jd.blockchain.crypto.impl.def.hash.SHA256HashFunction; | |||
import com.jd.blockchain.crypto.impl.sm.hash.SM3HashFunction; | |||
public class HashCryptographyImpl implements HashCryptography { | |||
private static final HashFunction SHA256_FUNC = new SHA256HashFunction(); | |||
private static final HashFunction RIPEMD160_FUNC = new RIPEMD160HashFunction(); | |||
private static final HashFunction SM3_FUNC = new SM3HashFunction(); | |||
// private static final HashFunction JNISHA256_FUNC = new JNISHA256HashFunction(); | |||
// private static final HashFunction JNIRIPEMD160_FUNC = new JNIRIPEMD160HashFunction(); | |||
@Override | |||
public HashFunction getFunction(CryptoAlgorithm algorithm) { | |||
// 遍历哈希算法,如果满足,则返回实例 | |||
switch (algorithm) { | |||
case SHA256: | |||
return SHA256_FUNC; | |||
case RIPEMD160: | |||
return RIPEMD160_FUNC; | |||
case SM3: | |||
return SM3_FUNC; | |||
// case JNISHA256: | |||
// return JNISHA256_FUNC; | |||
// case JNIRIPEMD160: | |||
// return JNIRIPEMD160_FUNC; | |||
default: | |||
break; | |||
} | |||
throw new IllegalArgumentException("The specified algorithm is not hash algorithm!"); | |||
} | |||
@Override | |||
public boolean verify(byte[] digestBytes, byte[] data) { | |||
HashDigest hashDigest = resolveHashDigest(digestBytes); | |||
return verify(hashDigest,data); | |||
} | |||
@Override | |||
public boolean verify(HashDigest digest, byte[] data) { | |||
CryptoAlgorithm algorithm = digest.getAlgorithm(); | |||
return getFunction(algorithm).verify(digest, data); | |||
} | |||
@Override | |||
public HashDigest resolveHashDigest(byte[] digestBytes) { | |||
HashDigest hashDigest = tryResolveHashDigest(digestBytes); | |||
if (hashDigest == null) | |||
throw new IllegalArgumentException("This digestBytes cannot be resolved!"); | |||
else return hashDigest; | |||
} | |||
@Override | |||
public HashDigest tryResolveHashDigest(byte[] digestBytes) { | |||
//遍历哈希函数,如果满足,则返回解析结果 | |||
if (SHA256_FUNC.supportHashDigest(digestBytes)) { | |||
return SHA256_FUNC.resolveHashDigest(digestBytes); | |||
} | |||
if (RIPEMD160_FUNC.supportHashDigest(digestBytes)) { | |||
return RIPEMD160_FUNC.resolveHashDigest(digestBytes); | |||
} | |||
if (SM3_FUNC.supportHashDigest(digestBytes)) { | |||
return SM3_FUNC.resolveHashDigest(digestBytes); | |||
} | |||
// if (JNISHA256_FUNC.supportHashDigest(digestBytes)) { | |||
// return JNISHA256_FUNC.resolveHashDigest(digestBytes); | |||
// } | |||
// if (JNIRIPEMD160_FUNC.supportHashDigest(digestBytes)) { | |||
// return JNIRIPEMD160_FUNC.resolveHashDigest(digestBytes); | |||
// } | |||
//否则返回null | |||
return null; | |||
} | |||
} |
@@ -0,0 +1,130 @@ | |||
//package com.jd.blockchain.crypto.impl.jni.asymmetric; | |||
// | |||
//import com.jd.blockchain.crypto.CryptoAlgorithm; | |||
//import com.jd.blockchain.crypto.asymmetric.*; | |||
//import com.jd.blockchain.crypto.jniutils.asymmetric.JNIED25519Utils; | |||
// | |||
//import static com.jd.blockchain.crypto.CryptoAlgorithm.JNIED25519; | |||
//import static com.jd.blockchain.crypto.CryptoBytes.ALGORYTHM_BYTES; | |||
//import static com.jd.blockchain.crypto.CryptoKeyType.PRIV_KEY; | |||
//import static com.jd.blockchain.crypto.CryptoKeyType.PUB_KEY; | |||
//import static com.jd.blockchain.crypto.base.BaseCryptoKey.KEY_TYPE_BYTES; | |||
// | |||
//public class JNIED25519SignatureFunction implements SignatureFunction { | |||
// | |||
// private static final int PUBKEY_SIZE = 32; | |||
// private static final int PRIVKEY_SIZE = 32; | |||
// private static final int DIGEST_SIZE = 64; | |||
// | |||
// private static final int PUBKEY_LENGTH = ALGORYTHM_BYTES + KEY_TYPE_BYTES + PUBKEY_SIZE; | |||
// private static final int PRIVKEY_LENGTH = ALGORYTHM_BYTES + KEY_TYPE_BYTES + PRIVKEY_SIZE; | |||
// private static final int SIGNATUREDIGEST_LENGTH = ALGORYTHM_BYTES + DIGEST_SIZE; | |||
// | |||
// public JNIED25519SignatureFunction() { | |||
// } | |||
// | |||
// @Override | |||
// public SignatureDigest sign(PrivKey privKey, byte[] data) { | |||
// | |||
// if (data == null) | |||
// throw new IllegalArgumentException("This data is null!"); | |||
// | |||
// JNIED25519Utils ed25519 = new JNIED25519Utils(); | |||
// | |||
// byte[] rawPrivKeyBytes = privKey.getRawKeyBytes(); | |||
// byte[] rawPubKeyBytes = ed25519.getPubKey(rawPrivKeyBytes); | |||
// | |||
// // 验证原始私钥长度为256比特,即32字节 | |||
// if (rawPrivKeyBytes.length != PRIVKEY_SIZE) | |||
// throw new IllegalArgumentException("This key has wrong format!"); | |||
// | |||
// // 验证密钥数据的算法标识对应JNIED25519签名算法 | |||
// if (privKey.getAlgorithm() != JNIED25519) | |||
// throw new IllegalArgumentException("This key is not ED25519 private key!"); | |||
// | |||
// // 调用JNIED25519签名算法计算签名结果 | |||
// return new SignatureDigest(JNIED25519, ed25519.sign(data, rawPrivKeyBytes, rawPubKeyBytes)); | |||
// } | |||
// | |||
// @Override | |||
// public boolean verify(SignatureDigest digest, PubKey pubKey, byte[] data) { | |||
// | |||
// JNIED25519Utils ed25519 = new JNIED25519Utils(); | |||
// | |||
// byte[] rawPubKeyBytes = pubKey.getRawKeyBytes(); | |||
// byte[] rawDigestBytes = digest.getRawDigest(); | |||
// | |||
// // 验证原始公钥长度为256比特,即32字节 | |||
// if (rawPubKeyBytes.length != PUBKEY_SIZE) | |||
// throw new IllegalArgumentException("This key has wrong format!"); | |||
// | |||
// // 验证密钥数据的算法标识对应JNIED25519签名算法 | |||
// if (pubKey.getAlgorithm() != JNIED25519) | |||
// throw new IllegalArgumentException("This key is not ED25519 public key!"); | |||
// | |||
// // 验证密文数据的算法标识对应JNIED25519签名算法,并且原始摘要长度为64字节 | |||
// if (digest.getAlgorithm() != JNIED25519 || rawDigestBytes.length != DIGEST_SIZE) | |||
// throw new IllegalArgumentException("This is not ED25519 signature digest!"); | |||
// | |||
// // 调用JNIED25519验签算法验证签名结果 | |||
// return ed25519.verify(data, rawPubKeyBytes, rawDigestBytes); | |||
// } | |||
// | |||
// @Override | |||
// public boolean supportPrivKey(byte[] privKeyBytes) { | |||
// // 验证输入字节数组长度=算法标识长度+密钥类型长度+密钥长度,密钥数据的算法标识对应JNIED25519签名算法,并且密钥类型是私钥 | |||
// return privKeyBytes.length == PRIVKEY_LENGTH | |||
// && privKeyBytes[0] == JNIED25519.CODE && privKeyBytes[1] == PRIV_KEY.CODE; | |||
// } | |||
// | |||
// @Override | |||
// public PrivKey resolvePrivKey(byte[] privKeyBytes) { | |||
// // 由框架调用 support 方法检查有效性,在此不做重复检查; | |||
// return new PrivKey(privKeyBytes); | |||
// } | |||
// | |||
// @Override | |||
// public boolean supportPubKey(byte[] pubKeyBytes) { | |||
// // 验证输入字节数组长度=算法标识长度+密钥类型长度+密钥长度,密钥数据的算法标识对应JNIED25519签名算法,并且密钥类型是公钥 | |||
// return pubKeyBytes.length == PUBKEY_LENGTH && | |||
// pubKeyBytes[0] == JNIED25519.CODE && pubKeyBytes[1] == PUB_KEY.CODE; | |||
// | |||
// } | |||
// | |||
// @Override | |||
// public PubKey resolvePubKey(byte[] pubKeyBytes) { | |||
// // 由框架调用 support 方法检查有效性,在此不做重复检查; | |||
// return new PubKey(pubKeyBytes); | |||
// } | |||
// | |||
// @Override | |||
// public boolean supportDigest(byte[] digestBytes) { | |||
// // 验证输入字节数组长度=算法标识长度+摘要长度,字节数组的算法标识对应JNIED25519算法 | |||
// return digestBytes.length == SIGNATUREDIGEST_LENGTH && digestBytes[0] == JNIED25519.CODE; | |||
// } | |||
// | |||
// @Override | |||
// public SignatureDigest resolveDigest(byte[] digestBytes) { | |||
// // 由框架调用 support 方法检查有效性,在此不做重复检查; | |||
// return new SignatureDigest(digestBytes); | |||
// } | |||
// | |||
// @Override | |||
// public CryptoAlgorithm getAlgorithm() { | |||
// return JNIED25519; | |||
// } | |||
// | |||
// @Override | |||
// public CryptoKeyPair generateKeyPair() { | |||
// | |||
// JNIED25519Utils ed25519 = new JNIED25519Utils(); | |||
// byte[] rawPrivKeyBytes = new byte[PRIVKEY_SIZE]; | |||
// byte[] rawPubKeyBytes = new byte[PUBKEY_SIZE]; | |||
// | |||
// // 调用JNIED25519算法的密钥生成算法生成公私钥对 | |||
// ed25519.generateKeyPair(rawPrivKeyBytes, rawPubKeyBytes); | |||
// | |||
// return new CryptoKeyPair(new PubKey(JNIED25519, rawPubKeyBytes), new PrivKey(JNIED25519, rawPrivKeyBytes)); | |||
// | |||
// } | |||
//} |
@@ -0,0 +1,53 @@ | |||
//package com.jd.blockchain.crypto.impl.jni.hash; | |||
// | |||
//import com.jd.blockchain.crypto.CryptoAlgorithm; | |||
//import com.jd.blockchain.crypto.hash.HashDigest; | |||
//import com.jd.blockchain.crypto.hash.HashFunction; | |||
//import com.jd.blockchain.crypto.jniutils.hash.JNIRIPEMD160Utils; | |||
// | |||
//import java.util.Arrays; | |||
// | |||
//import static com.jd.blockchain.crypto.CryptoAlgorithm.JNIRIPEMD160; | |||
//import static com.jd.blockchain.crypto.CryptoBytes.ALGORYTHM_BYTES; | |||
// | |||
//public class JNIRIPEMD160HashFunction implements HashFunction { | |||
// | |||
// private static final int DIGEST_BYTES = 160 / 8; | |||
// | |||
// private static final int DIGEST_LENGTH = ALGORYTHM_BYTES + DIGEST_BYTES; | |||
// | |||
// @Override | |||
// public CryptoAlgorithm getAlgorithm() { | |||
// return JNIRIPEMD160; | |||
// } | |||
// | |||
// @Override | |||
// public HashDigest hash(byte[] data) { | |||
// | |||
// if (data == null) | |||
// throw new IllegalArgumentException("This data is null!"); | |||
// | |||
// JNIRIPEMD160Utils ripemd160 = new JNIRIPEMD160Utils(); | |||
// byte[] digestBytes = ripemd160.hash(data); | |||
// return new HashDigest(JNIRIPEMD160, digestBytes); | |||
// } | |||
// | |||
// @Override | |||
// public boolean verify(HashDigest digest, byte[] data) { | |||
// HashDigest hashDigest = hash(data); | |||
// return Arrays.equals(hashDigest.toBytes(), digest.toBytes()); | |||
// } | |||
// | |||
// @Override | |||
// public boolean supportHashDigest(byte[] digestBytes) { | |||
// // 验证输入字节数组长度=算法标识长度+摘要长度,字节数组的算法标识对应JNIRIPEMD160算法 | |||
// return digestBytes.length == DIGEST_LENGTH && JNIRIPEMD160.CODE == digestBytes[0]; | |||
// } | |||
// | |||
// @Override | |||
// public HashDigest resolveHashDigest(byte[] digestBytes) { | |||
// // 由框架调用 support 方法检查有效性,在此不做重复检查; | |||
// return new HashDigest(digestBytes); | |||
// } | |||
//} | |||
// |
@@ -0,0 +1,53 @@ | |||
//package com.jd.blockchain.crypto.impl.jni.hash; | |||
// | |||
//import com.jd.blockchain.crypto.CryptoAlgorithm; | |||
//import com.jd.blockchain.crypto.hash.HashDigest; | |||
//import com.jd.blockchain.crypto.hash.HashFunction; | |||
//import com.jd.blockchain.crypto.jniutils.hash.JNISHA256Utils; | |||
// | |||
//import java.util.Arrays; | |||
// | |||
//import static com.jd.blockchain.crypto.CryptoAlgorithm.JNISHA256; | |||
//import static com.jd.blockchain.crypto.CryptoBytes.ALGORYTHM_BYTES; | |||
// | |||
//public class JNISHA256HashFunction implements HashFunction { | |||
// | |||
// private static final int DIGEST_BYTES = 256/8; | |||
// | |||
// private static final int DIGEST_LENGTH = ALGORYTHM_BYTES + DIGEST_BYTES; | |||
// | |||
// @Override | |||
// public CryptoAlgorithm getAlgorithm() { | |||
// return JNISHA256; | |||
// } | |||
// | |||
// @Override | |||
// public HashDigest hash(byte[] data) { | |||
// | |||
// if (data == null) | |||
// throw new IllegalArgumentException("This data is null!"); | |||
// | |||
// JNISHA256Utils sha256 = new JNISHA256Utils(); | |||
// byte[] digestBytes = sha256.hash(data); | |||
// return new HashDigest(JNISHA256,digestBytes); | |||
// } | |||
// | |||
// @Override | |||
// public boolean verify(HashDigest digest, byte[] data) { | |||
// HashDigest hashDigest=hash(data); | |||
// return Arrays.equals(hashDigest.toBytes(),digest.toBytes()); | |||
// } | |||
// | |||
// @Override | |||
// public boolean supportHashDigest(byte[] digestBytes) { | |||
// // 验证输入字节数组长度=算法标识长度+摘要长度,字节数组的算法标识对应JNISHA256算法 | |||
// return digestBytes.length == DIGEST_LENGTH && JNISHA256.CODE == digestBytes[0]; | |||
// } | |||
// | |||
// @Override | |||
// public HashDigest resolveHashDigest(byte[] hashDigestBytes) { | |||
// // 由框架调用 support 方法检查有效性,在此不做重复检查; | |||
// return new HashDigest(hashDigestBytes); | |||
// } | |||
// | |||
//} |
@@ -0,0 +1,946 @@ | |||
package test.com.jd.blockchain.crypto.asymmetric; | |||
import com.jd.blockchain.crypto.Ciphertext; | |||
import com.jd.blockchain.crypto.CryptoAlgorithm; | |||
import com.jd.blockchain.crypto.CryptoException; | |||
import com.jd.blockchain.crypto.CryptoKeyType; | |||
import com.jd.blockchain.crypto.asymmetric.*; | |||
import com.jd.blockchain.crypto.impl.AsymmtricCryptographyImpl; | |||
import com.jd.blockchain.utils.io.BytesUtils; | |||
import org.junit.Test; | |||
import java.util.Random; | |||
import static com.jd.blockchain.crypto.CryptoKeyType.PRIV_KEY; | |||
import static com.jd.blockchain.crypto.CryptoKeyType.PUB_KEY; | |||
import static org.junit.Assert.*; | |||
import static org.junit.Assert.assertNotNull; | |||
public class AsymmtricCryptographyImplTest { | |||
@Test | |||
public void testGenerateKeyPair() { | |||
AsymmetricCryptography asymmetricCrypto = new AsymmtricCryptographyImpl(); | |||
//test ED25519 | |||
CryptoAlgorithm algorithm = CryptoAlgorithm.ED25519; | |||
CryptoKeyPair keyPair = asymmetricCrypto.generateKeyPair(algorithm); | |||
assertNotNull(keyPair); | |||
PubKey pubKey = keyPair.getPubKey(); | |||
PrivKey privKey = keyPair.getPrivKey(); | |||
assertNotNull(pubKey); | |||
assertNotNull(privKey); | |||
assertEquals(algorithm,pubKey.getAlgorithm()); | |||
assertEquals(algorithm,privKey.getAlgorithm()); | |||
assertEquals(32,pubKey.getRawKeyBytes().length); | |||
assertEquals(32,privKey.getRawKeyBytes().length); | |||
byte[] pubKeyBytes = pubKey.toBytes(); | |||
byte[] privKeyBytes = privKey.toBytes(); | |||
assertEquals(32+1+1,pubKeyBytes.length); | |||
assertEquals(32+1+1,privKeyBytes.length); | |||
assertEquals(CryptoAlgorithm.ED25519.CODE,pubKeyBytes[0]); | |||
assertEquals(CryptoAlgorithm.ED25519.CODE,privKeyBytes[0]); | |||
assertEquals(CryptoAlgorithm.ED25519, CryptoAlgorithm.valueOf(pubKey.getAlgorithm().CODE)); | |||
assertEquals(CryptoAlgorithm.ED25519, CryptoAlgorithm.valueOf(privKey.getAlgorithm().CODE)); | |||
assertEquals(pubKey.getKeyType().CODE,pubKeyBytes[1]); | |||
assertEquals(privKey.getKeyType().CODE,privKeyBytes[1]); | |||
//test SM2 | |||
algorithm = CryptoAlgorithm.SM2; | |||
keyPair = asymmetricCrypto.generateKeyPair(algorithm); | |||
assertNotNull(keyPair); | |||
pubKey = keyPair.getPubKey(); | |||
privKey = keyPair.getPrivKey(); | |||
assertNotNull(pubKey); | |||
assertNotNull(privKey); | |||
assertEquals(algorithm,pubKey.getAlgorithm()); | |||
assertEquals(algorithm,privKey.getAlgorithm()); | |||
assertEquals(65,pubKey.getRawKeyBytes().length); | |||
assertEquals(32,privKey.getRawKeyBytes().length); | |||
pubKeyBytes = pubKey.toBytes(); | |||
privKeyBytes = privKey.toBytes(); | |||
assertEquals(32+1+1,privKeyBytes.length); | |||
assertEquals(65+1+1,pubKeyBytes.length); | |||
assertEquals(CryptoAlgorithm.SM2.CODE,pubKeyBytes[0]); | |||
assertEquals(CryptoAlgorithm.SM2.CODE,privKeyBytes[0]); | |||
assertEquals(CryptoAlgorithm.SM2, CryptoAlgorithm.valueOf(pubKey.getAlgorithm().CODE)); | |||
assertEquals(CryptoAlgorithm.SM2, CryptoAlgorithm.valueOf(privKey.getAlgorithm().CODE)); | |||
assertEquals(pubKey.getKeyType().CODE,pubKeyBytes[1]); | |||
assertEquals(privKey.getKeyType().CODE,privKeyBytes[1]); | |||
//test JNIED25519 | |||
// algorithm = CryptoAlgorithm.JNIED25519; | |||
// keyPair = asymmetricCrypto.generateKeyPair(algorithm); | |||
// | |||
// assertNotNull(keyPair); | |||
// | |||
// pubKey = keyPair.getPubKey(); | |||
// privKey = keyPair.getPrivKey(); | |||
// | |||
// assertNotNull(pubKey); | |||
// assertNotNull(privKey); | |||
// | |||
// assertEquals(algorithm,pubKey.getAlgorithm()); | |||
// assertEquals(algorithm,privKey.getAlgorithm()); | |||
// | |||
// assertEquals(32,pubKey.getRawKeyBytes().length); | |||
// assertEquals(32,privKey.getRawKeyBytes().length); | |||
// | |||
// pubKeyBytes = pubKey.toBytes(); | |||
// privKeyBytes = privKey.toBytes(); | |||
// | |||
// assertEquals(32+1+1,pubKeyBytes.length); | |||
// assertEquals(32+1+1,privKeyBytes.length); | |||
// | |||
// assertEquals(CryptoAlgorithm.JNIED25519.CODE,pubKeyBytes[0]); | |||
// assertEquals(CryptoAlgorithm.JNIED25519.CODE,privKeyBytes[0]); | |||
// assertEquals(CryptoAlgorithm.JNIED25519, CryptoAlgorithm.valueOf(pubKey.getAlgorithm().CODE)); | |||
// assertEquals(CryptoAlgorithm.JNIED25519, CryptoAlgorithm.valueOf(privKey.getAlgorithm().CODE)); | |||
// | |||
// assertEquals(pubKey.getKeyType().CODE,pubKeyBytes[1]); | |||
// assertEquals(privKey.getKeyType().CODE,privKeyBytes[1]); | |||
} | |||
@Test | |||
public void testGetSignatureFunction() { | |||
AsymmetricCryptography asymmetricCrypto = new AsymmtricCryptographyImpl(); | |||
Random random = new Random(); | |||
//test ED25519 | |||
CryptoAlgorithm algorithm = CryptoAlgorithm.ED25519; | |||
// 测试256字节的消息进行签名 | |||
byte[] data = new byte[256]; | |||
random.nextBytes(data); | |||
verifyGetSignatureFunction(asymmetricCrypto,algorithm,data,32,32,64,null); | |||
//错误的算法标识 | |||
verifyGetSignatureFunction(asymmetricCrypto,CryptoAlgorithm.AES,data,32,32,64,IllegalArgumentException.class); | |||
data = null; | |||
verifyGetSignatureFunction(asymmetricCrypto,algorithm,data,32,32,64,NullPointerException.class); | |||
//test SM2 | |||
algorithm = CryptoAlgorithm.SM2; | |||
// 测试256字节的消息进行签名 | |||
data = new byte[256]; | |||
random.nextBytes(data); | |||
verifyGetSignatureFunction(asymmetricCrypto,algorithm,data,65,32,64,null); | |||
//错误的算法标识 | |||
verifyGetSignatureFunction(asymmetricCrypto,CryptoAlgorithm.AES,data,65,32,64,IllegalArgumentException.class); | |||
data = null; | |||
verifyGetSignatureFunction(asymmetricCrypto,algorithm,data,65,32,64,NullPointerException.class); | |||
// //test JNNIED25519 | |||
// algorithm = CryptoAlgorithm.JNIED25519; | |||
// | |||
// // 测试256字节的消息进行签名 | |||
// data = new byte[256]; | |||
// random.nextBytes(data); | |||
// verifyGetSignatureFunction(asymmetricCrypto,algorithm,data,32,32,64,null); | |||
// | |||
// //错误的算法标识 | |||
// verifyGetSignatureFunction(asymmetricCrypto,CryptoAlgorithm.AES,data,32,32,64,IllegalArgumentException.class); | |||
// | |||
// data = null; | |||
// verifyGetSignatureFunction(asymmetricCrypto,algorithm,data,32,32,64,IllegalArgumentException.class); | |||
} | |||
private void verifyGetSignatureFunction(AsymmetricCryptography asymmetricCrypto, CryptoAlgorithm algorithm, byte[] data, | |||
int expectedPubKeyLength, int expectedPrivKeyLength, | |||
int expectedSignatureDigestLength, Class<?> expectedException){ | |||
//初始化一个异常 | |||
Exception actualEx = null; | |||
try { | |||
SignatureFunction sf = asymmetricCrypto.getSignatureFunction(algorithm); | |||
assertNotNull(sf); | |||
CryptoKeyPair keyPair = sf.generateKeyPair(); | |||
PubKey pubKey = keyPair.getPubKey(); | |||
PrivKey privKey = keyPair.getPrivKey(); | |||
byte[] rawPubKeyBytes = pubKey.getRawKeyBytes(); | |||
byte[] rawPrivKeyBytes = privKey.getRawKeyBytes(); | |||
byte[] pubKeyBytes = pubKey.toBytes(); | |||
byte[] privKeyBytes = privKey.toBytes(); | |||
assertEquals(algorithm, pubKey.getAlgorithm()); | |||
assertEquals(algorithm, privKey.getAlgorithm()); | |||
assertEquals(expectedPubKeyLength,rawPubKeyBytes.length); | |||
assertEquals(expectedPrivKeyLength,rawPrivKeyBytes.length); | |||
assertArrayEquals(BytesUtils.concat(new byte[]{algorithm.CODE},new byte[]{CryptoKeyType.PUB_KEY.CODE},rawPubKeyBytes), pubKeyBytes); | |||
assertArrayEquals(BytesUtils.concat(new byte[]{algorithm.CODE},new byte[]{CryptoKeyType.PRIV_KEY.CODE},rawPrivKeyBytes), privKeyBytes); | |||
SignatureDigest signatureDigest = sf.sign(privKey,data); | |||
byte[] rawDigest = signatureDigest.getRawDigest(); | |||
assertEquals(algorithm,signatureDigest.getAlgorithm()); | |||
assertEquals(expectedSignatureDigestLength,rawDigest.length); | |||
byte[] signatureDigestBytes = signatureDigest.toBytes(); | |||
assertArrayEquals(BytesUtils.concat(new byte[]{algorithm.CODE},rawDigest),signatureDigestBytes); | |||
assertTrue(signatureDigest.equals(signatureDigest)); | |||
assertEquals(signatureDigest.hashCode(),signatureDigest.hashCode()); | |||
assertTrue(sf.verify(signatureDigest,pubKey,data)); | |||
assertTrue(sf.supportPubKey(pubKeyBytes)); | |||
assertTrue(sf.supportPrivKey(privKeyBytes)); | |||
assertTrue(sf.supportDigest(signatureDigestBytes)); | |||
assertEquals(pubKey,sf.resolvePubKey(pubKeyBytes)); | |||
assertEquals(privKey,sf.resolvePrivKey(privKeyBytes)); | |||
assertEquals(signatureDigest,sf.resolveDigest(signatureDigestBytes)); | |||
assertEquals(algorithm,sf.getAlgorithm()); | |||
} catch (Exception e){ | |||
actualEx = e; | |||
} | |||
if (expectedException == null) { | |||
assertNull(actualEx); | |||
} | |||
else { | |||
assertNotNull(actualEx); | |||
assertTrue(expectedException.isAssignableFrom(actualEx.getClass())); | |||
} | |||
} | |||
@Test | |||
public void testVerify() { | |||
AsymmetricCryptography asymmetricCrypto = new AsymmtricCryptographyImpl(); | |||
Random randomData = new Random(); | |||
//test ED25519 | |||
CryptoAlgorithm algorithm = CryptoAlgorithm.ED25519; | |||
// 测试256字节的消息进行签名 | |||
byte[] data = new byte[256]; | |||
randomData.nextBytes(data); | |||
SignatureFunction sf = asymmetricCrypto.getSignatureFunction(algorithm); | |||
CryptoKeyPair keyPair = sf.generateKeyPair(); | |||
byte[] pubKeyBytes = keyPair.getPubKey().toBytes(); | |||
byte[] signatureDigestBytes = sf.sign(keyPair.getPrivKey(),data).toBytes(); | |||
verifyVerify(asymmetricCrypto,true,data,pubKeyBytes,signatureDigestBytes,null); | |||
//签名数据末尾两个字节丢失情况下,抛出异常 | |||
byte[] truncatedSignatureDigestBytes = new byte[signatureDigestBytes.length-2]; | |||
System.arraycopy(signatureDigestBytes,0,truncatedSignatureDigestBytes,0,truncatedSignatureDigestBytes.length); | |||
verifyVerify(asymmetricCrypto,false,data,pubKeyBytes,truncatedSignatureDigestBytes,IllegalArgumentException.class); | |||
byte[] signatureDigestBytesWithWrongAlgCode = signatureDigestBytes; | |||
signatureDigestBytesWithWrongAlgCode[0] = CryptoAlgorithm.SHA256.CODE; | |||
verifyVerify(asymmetricCrypto,false,data,pubKeyBytes,signatureDigestBytesWithWrongAlgCode,IllegalArgumentException.class); | |||
signatureDigestBytes = null; | |||
verifyVerify(asymmetricCrypto,false,data,pubKeyBytes,signatureDigestBytes,NullPointerException.class); | |||
//test SM2 | |||
algorithm = CryptoAlgorithm.SM2; | |||
// 测试256字节的消息进行签名 | |||
data = new byte[256]; | |||
randomData.nextBytes(data); | |||
sf = asymmetricCrypto.getSignatureFunction(algorithm); | |||
keyPair = sf.generateKeyPair(); | |||
pubKeyBytes = keyPair.getPubKey().toBytes(); | |||
signatureDigestBytes = sf.sign(keyPair.getPrivKey(),data).toBytes(); | |||
verifyVerify(asymmetricCrypto,true,data,pubKeyBytes,signatureDigestBytes,null); | |||
//签名数据末尾两个字节丢失情况下,抛出异常 | |||
truncatedSignatureDigestBytes = new byte[signatureDigestBytes.length-2]; | |||
System.arraycopy(signatureDigestBytes,0,truncatedSignatureDigestBytes,0,truncatedSignatureDigestBytes.length); | |||
verifyVerify(asymmetricCrypto,false,data,pubKeyBytes,truncatedSignatureDigestBytes,IllegalArgumentException.class); | |||
signatureDigestBytesWithWrongAlgCode = signatureDigestBytes; | |||
signatureDigestBytesWithWrongAlgCode[0] = CryptoAlgorithm.SHA256.CODE; | |||
verifyVerify(asymmetricCrypto,false,data,pubKeyBytes,signatureDigestBytesWithWrongAlgCode,IllegalArgumentException.class); | |||
signatureDigestBytes = null; | |||
verifyVerify(asymmetricCrypto,false,data,pubKeyBytes,signatureDigestBytes,NullPointerException.class); | |||
// //test JNIED25519 | |||
// algorithm = CryptoAlgorithm.JNIED25519; | |||
// | |||
// // 测试256字节的消息进行签名 | |||
// data = new byte[256]; | |||
// randomData.nextBytes(data); | |||
// sf = asymmetricCrypto.getSignatureFunction(algorithm); | |||
// keyPair = sf.generateKeyPair(); | |||
// pubKeyBytes = keyPair.getPubKey().toBytes(); | |||
// | |||
// signatureDigestBytes = sf.sign(keyPair.getPrivKey(),data).toBytes(); | |||
// verifyVerify(asymmetricCrypto,true,data,pubKeyBytes,signatureDigestBytes,null); | |||
// | |||
// //签名数据末尾两个字节丢失情况下,抛出异常 | |||
// truncatedSignatureDigestBytes = new byte[signatureDigestBytes.length-2]; | |||
// System.arraycopy(signatureDigestBytes,0,truncatedSignatureDigestBytes,0,truncatedSignatureDigestBytes.length); | |||
// verifyVerify(asymmetricCrypto,false,data,pubKeyBytes,truncatedSignatureDigestBytes,IllegalArgumentException.class); | |||
// | |||
// signatureDigestBytesWithWrongAlgCode = signatureDigestBytes; | |||
// signatureDigestBytesWithWrongAlgCode[0] = CryptoAlgorithm.SHA256.CODE; | |||
// verifyVerify(asymmetricCrypto,false,data,pubKeyBytes,signatureDigestBytesWithWrongAlgCode,IllegalArgumentException.class); | |||
// | |||
// signatureDigestBytes = null; | |||
// verifyVerify(asymmetricCrypto,false,data,pubKeyBytes,signatureDigestBytes,NullPointerException.class); | |||
} | |||
private void verifyVerify(AsymmetricCryptography asymmetricCrypto,boolean expectedResult,byte[] data, | |||
byte[] pubKeyBytes, byte[] signatureDigestBytes, Class<?> expectedException){ | |||
//初始化一个异常 | |||
Exception actualEx = null; | |||
boolean pass = false; | |||
try { | |||
pass = asymmetricCrypto.verify(signatureDigestBytes,pubKeyBytes,data); | |||
} | |||
catch (Exception e){ | |||
actualEx = e; | |||
} | |||
assertEquals(expectedResult, pass); | |||
if (expectedException == null) { | |||
assertNull(actualEx); | |||
} | |||
else { | |||
assertNotNull(actualEx); | |||
assertTrue(expectedException.isAssignableFrom(actualEx.getClass())); | |||
} | |||
} | |||
@Test | |||
public void testGetAsymmetricEncryptionFunction() { | |||
AsymmetricCryptography asymmetricCrypto = new AsymmtricCryptographyImpl(); | |||
Random random = new Random(); | |||
//test SM2 | |||
CryptoAlgorithm algorithm = CryptoAlgorithm.SM2; | |||
//Case 1: SM2Encryption with 16 bytes data | |||
byte[] data = new byte[16]; | |||
random.nextBytes(data); | |||
verifyGetAsymmetricEncryptionFunction(asymmetricCrypto, algorithm,65,32,65+16+32,data,null); | |||
//Case 2: SM2Encryption with 256 bytes data | |||
data = new byte[256]; | |||
random.nextBytes(data); | |||
verifyGetAsymmetricEncryptionFunction(asymmetricCrypto, algorithm,65,32,65+256+32,data,null); | |||
//Case 3: SM2Encryption with 1 bytes data | |||
data = new byte[3]; | |||
random.nextBytes(data); | |||
verifyGetAsymmetricEncryptionFunction(asymmetricCrypto, algorithm,65,32,65+3+32,data,null); | |||
//Case 4: SM2Encryption with wrong algorithm | |||
verifyGetAsymmetricEncryptionFunction(asymmetricCrypto,CryptoAlgorithm.AES,65,32,65+3+32,data,IllegalArgumentException.class); | |||
//Case 5: SM2Encryption with null data | |||
data = null; | |||
verifyGetAsymmetricEncryptionFunction(asymmetricCrypto,algorithm,65,32,65+32,data,NullPointerException.class); | |||
} | |||
private void verifyGetAsymmetricEncryptionFunction(AsymmetricCryptography asymmetricCrypto, CryptoAlgorithm algorithm, | |||
int expectedPubKeyLength, int expectedPrivKeyLength, | |||
int expectedCiphertextLength, byte[] data, Class<?> expectedException){ | |||
//初始化一个异常 | |||
Exception actualEx = null; | |||
try { | |||
AsymmetricEncryptionFunction aef = asymmetricCrypto.getAsymmetricEncryptionFunction(algorithm); | |||
//验证获取的算法实例非空 | |||
assertNotNull(aef); | |||
CryptoKeyPair keyPair = aef.generateKeyPair(); | |||
PubKey pubKey = keyPair.getPubKey(); | |||
PrivKey privKey = keyPair.getPrivKey(); | |||
byte[] rawPubKeyBytes = pubKey.getRawKeyBytes(); | |||
byte[] rawPrivKeyBytes = privKey.getRawKeyBytes(); | |||
byte[] pubKeyBytes = pubKey.toBytes(); | |||
byte[] privKeyBytes = privKey.toBytes(); | |||
assertEquals(algorithm, pubKey.getAlgorithm()); | |||
assertEquals(algorithm, privKey.getAlgorithm()); | |||
assertEquals(expectedPubKeyLength,rawPubKeyBytes.length); | |||
assertEquals(expectedPrivKeyLength,rawPrivKeyBytes.length); | |||
assertArrayEquals(BytesUtils.concat(new byte[]{algorithm.CODE},new byte[]{CryptoKeyType.PUB_KEY.CODE},rawPubKeyBytes), pubKeyBytes); | |||
assertArrayEquals(BytesUtils.concat(new byte[]{algorithm.CODE},new byte[]{CryptoKeyType.PRIV_KEY.CODE},rawPrivKeyBytes), privKeyBytes); | |||
Ciphertext ciphertext = aef.encrypt(pubKey,data); | |||
byte[] rawCiphertextBytes = ciphertext.getRawCiphertext(); | |||
assertEquals(algorithm,ciphertext.getAlgorithm()); | |||
assertEquals(expectedCiphertextLength,rawCiphertextBytes.length); | |||
byte[] ciphertextBytes = ciphertext.toBytes(); | |||
assertArrayEquals(BytesUtils.concat(new byte[]{algorithm.CODE},rawCiphertextBytes),ciphertextBytes); | |||
assertArrayEquals(data,aef.decrypt(privKey,ciphertext)); | |||
assertTrue(aef.supportPubKey(pubKeyBytes)); | |||
assertTrue(aef.supportPrivKey(privKeyBytes)); | |||
assertTrue(aef.supportCiphertext(ciphertextBytes)); | |||
assertEquals(pubKey,aef.resolvePubKey(pubKeyBytes)); | |||
assertEquals(privKey,aef.resolvePrivKey(privKeyBytes)); | |||
assertEquals(ciphertext,aef.resolveCiphertext(ciphertextBytes)); | |||
assertEquals(algorithm,aef.getAlgorithm()); | |||
}catch (Exception e){ | |||
actualEx = e; | |||
} | |||
if(expectedException == null){ | |||
assertNull(actualEx); | |||
} | |||
else { | |||
assertNotNull(actualEx); | |||
assertTrue(expectedException.isAssignableFrom(actualEx.getClass())); | |||
} | |||
} | |||
@Test | |||
public void testDecrypt() { | |||
AsymmetricCryptography asymmetricCrypto = new AsymmtricCryptographyImpl(); | |||
Random random = new Random(); | |||
byte[] data = new byte[16]; | |||
random.nextBytes(data); | |||
//test SM2 | |||
CryptoAlgorithm algorithm = CryptoAlgorithm.SM2; | |||
AsymmetricEncryptionFunction aef = asymmetricCrypto.getAsymmetricEncryptionFunction(algorithm); | |||
CryptoKeyPair keyPair = aef.generateKeyPair(); | |||
PubKey pubKey = keyPair.getPubKey(); | |||
PrivKey privKey = keyPair.getPrivKey(); | |||
byte[] rawPrivKeyBytes = privKey.getRawKeyBytes(); | |||
Ciphertext ciphertext = aef.encrypt(pubKey,data); | |||
byte[] ciphertextBytes = ciphertext.toBytes(); | |||
verifyDecrypt(asymmetricCrypto, algorithm, rawPrivKeyBytes, data, ciphertextBytes, null); | |||
//密钥的算法标识与密文的算法标识不一致情况 | |||
verifyDecrypt(asymmetricCrypto, CryptoAlgorithm.AES, rawPrivKeyBytes, data, ciphertextBytes, IllegalArgumentException.class); | |||
//密文末尾两个字节丢失情况下,抛出异常 | |||
byte[] truncatedCiphertextBytes = new byte[ciphertextBytes.length-2]; | |||
System.arraycopy(ciphertextBytes,0,truncatedCiphertextBytes,0,truncatedCiphertextBytes.length); | |||
verifyDecrypt(asymmetricCrypto, algorithm, rawPrivKeyBytes, data, truncatedCiphertextBytes, com.jd.blockchain.crypto.CryptoException.class); | |||
byte[] ciphertextBytesWithWrongAlgCode = ciphertextBytes; | |||
ciphertextBytesWithWrongAlgCode[0] = CryptoAlgorithm.SHA256.CODE; | |||
verifyDecrypt(asymmetricCrypto,algorithm,rawPrivKeyBytes,data,ciphertextBytesWithWrongAlgCode,IllegalArgumentException.class); | |||
ciphertextBytes = null; | |||
verifyDecrypt(asymmetricCrypto,algorithm,rawPrivKeyBytes,data,ciphertextBytes,NullPointerException.class); | |||
} | |||
private void verifyDecrypt(AsymmetricCryptography asymmetricCrypto, CryptoAlgorithm algorithm, | |||
byte[] key, byte[] data, byte[] ciphertextBytes, Class<?> expectedException){ | |||
Exception actualEx = null; | |||
try { | |||
PrivKey privKey = new PrivKey(algorithm,key); | |||
byte[] plaintext = asymmetricCrypto.decrypt(privKey.toBytes(), ciphertextBytes); | |||
//解密后的明文与初始的明文一致 | |||
assertArrayEquals(data,plaintext); | |||
} | |||
catch (Exception e){ | |||
actualEx = e; | |||
} | |||
if (expectedException == null) { | |||
assertNull(actualEx); | |||
} | |||
else { | |||
assertNotNull(actualEx); | |||
assertTrue(expectedException.isAssignableFrom(actualEx.getClass())); | |||
} | |||
} | |||
@Test | |||
public void testResolveCiphertext() { | |||
AsymmetricCryptography asymmetricCrypto = new AsymmtricCryptographyImpl(); | |||
Random random = new Random(); | |||
byte[] data = new byte[16]; | |||
random.nextBytes(data); | |||
//test SM2 | |||
CryptoAlgorithm algorithm = CryptoAlgorithm.SM2; | |||
AsymmetricEncryptionFunction aef = asymmetricCrypto.getAsymmetricEncryptionFunction(algorithm); | |||
CryptoKeyPair keyPair = aef.generateKeyPair(); | |||
PubKey pubKey = keyPair.getPubKey(); | |||
PrivKey privKey = keyPair.getPrivKey(); | |||
byte[] rawPrivKeyBytes = privKey.getRawKeyBytes(); | |||
Ciphertext ciphertext = aef.encrypt(pubKey,data); | |||
byte[] ciphertextBytes = ciphertext.toBytes(); | |||
verifyResolveCiphertext(asymmetricCrypto, algorithm, ciphertextBytes, null); | |||
//密文末尾两个字节丢失情况下,抛出异常 | |||
byte[] truncatedCiphertextBytes = new byte[ciphertextBytes.length-2]; | |||
System.arraycopy(ciphertextBytes,0,truncatedCiphertextBytes,0,truncatedCiphertextBytes.length); | |||
verifyDecrypt(asymmetricCrypto, algorithm, rawPrivKeyBytes, data, truncatedCiphertextBytes, CryptoException.class); | |||
byte[] ciphertextBytesWithWrongAlgCode = ciphertextBytes; | |||
ciphertextBytesWithWrongAlgCode[0] = CryptoAlgorithm.SHA256.CODE; | |||
verifyResolveCiphertext(asymmetricCrypto,algorithm,ciphertextBytesWithWrongAlgCode,IllegalArgumentException.class); | |||
ciphertextBytes = null; | |||
verifyResolveCiphertext(asymmetricCrypto,algorithm,ciphertextBytes,NullPointerException.class); | |||
} | |||
private void verifyResolveCiphertext(AsymmetricCryptography asymmetricCrypto, CryptoAlgorithm algorithm, byte[] ciphertextBytes, | |||
Class<?> expectedException){ | |||
Exception actualEx = null; | |||
try { | |||
Ciphertext ciphertext = asymmetricCrypto.resolveCiphertext(ciphertextBytes); | |||
assertNotNull(ciphertext); | |||
assertEquals(algorithm, ciphertext.getAlgorithm()); | |||
assertArrayEquals(ciphertextBytes, ciphertext.toBytes()); | |||
} | |||
catch (Exception e){ | |||
actualEx = e; | |||
} | |||
if (expectedException == null) { | |||
assertNull(actualEx); | |||
} | |||
else { | |||
assertNotNull(actualEx); | |||
assertTrue(expectedException.isAssignableFrom(actualEx.getClass())); | |||
} | |||
} | |||
@Test | |||
public void testTryResolveCiphertext() { | |||
} | |||
@Test | |||
public void testResolveSignatureDigest() { | |||
AsymmetricCryptography asymmetricCrypto = new AsymmtricCryptographyImpl(); | |||
Random randomData = new Random(); | |||
//test ED25519 | |||
CryptoAlgorithm algorithm = CryptoAlgorithm.ED25519; | |||
// 测试256字节的消息进行签名 | |||
byte[] data = new byte[256]; | |||
randomData.nextBytes(data); | |||
SignatureFunction sf = asymmetricCrypto.getSignatureFunction(algorithm); | |||
CryptoKeyPair keyPair = sf.generateKeyPair(); | |||
byte[] signatureDigestBytes = sf.sign(keyPair.getPrivKey(),data).toBytes(); | |||
verifyResolveSignatureDigest(asymmetricCrypto,algorithm,64,signatureDigestBytes,null); | |||
//签名数据末尾两个字节丢失情况下,抛出异常 | |||
byte[] truncatedSignatureDigestBytes = new byte[signatureDigestBytes.length-2]; | |||
System.arraycopy(signatureDigestBytes,0,truncatedSignatureDigestBytes,0,truncatedSignatureDigestBytes.length); | |||
verifyResolveSignatureDigest(asymmetricCrypto,algorithm,64,truncatedSignatureDigestBytes,IllegalArgumentException.class); | |||
signatureDigestBytes = null; | |||
verifyResolveSignatureDigest(asymmetricCrypto,algorithm,64,signatureDigestBytes,NullPointerException.class); | |||
//test SM2 | |||
algorithm = CryptoAlgorithm.SM2; | |||
// 测试256字节的消息进行签名 | |||
data = new byte[256]; | |||
randomData.nextBytes(data); | |||
sf = asymmetricCrypto.getSignatureFunction(algorithm); | |||
keyPair = sf.generateKeyPair(); | |||
signatureDigestBytes = sf.sign(keyPair.getPrivKey(),data).toBytes(); | |||
verifyResolveSignatureDigest(asymmetricCrypto,algorithm,64,signatureDigestBytes,null); | |||
//签名数据末尾两个字节丢失情况下,抛出异常 | |||
truncatedSignatureDigestBytes = new byte[signatureDigestBytes.length-2]; | |||
System.arraycopy(signatureDigestBytes,0,truncatedSignatureDigestBytes,0,truncatedSignatureDigestBytes.length); | |||
verifyResolveSignatureDigest(asymmetricCrypto,algorithm,64,truncatedSignatureDigestBytes,IllegalArgumentException.class); | |||
signatureDigestBytes = null; | |||
verifyResolveSignatureDigest(asymmetricCrypto,algorithm,64,signatureDigestBytes,NullPointerException.class); | |||
// //test JNIED25519 | |||
// algorithm = CryptoAlgorithm.JNIED25519; | |||
// | |||
// // 测试256字节的消息进行签名 | |||
// data = new byte[256]; | |||
// randomData.nextBytes(data); | |||
// sf = asymmetricCrypto.getSignatureFunction(algorithm); | |||
// keyPair = sf.generateKeyPair(); | |||
// | |||
// signatureDigestBytes = sf.sign(keyPair.getPrivKey(),data).toBytes(); | |||
// verifyResolveSignatureDigest(asymmetricCrypto,algorithm,64,signatureDigestBytes,null); | |||
// | |||
// //签名数据末尾两个字节丢失情况下,抛出异常 | |||
// truncatedSignatureDigestBytes = new byte[signatureDigestBytes.length-2]; | |||
// System.arraycopy(signatureDigestBytes,0,truncatedSignatureDigestBytes,0,truncatedSignatureDigestBytes.length); | |||
// verifyResolveSignatureDigest(asymmetricCrypto,algorithm,64,truncatedSignatureDigestBytes,IllegalArgumentException.class); | |||
// | |||
// signatureDigestBytes = null; | |||
// verifyResolveSignatureDigest(asymmetricCrypto,algorithm,64,signatureDigestBytes,NullPointerException.class); | |||
} | |||
private void verifyResolveSignatureDigest(AsymmetricCryptography asymmetricCrypto, CryptoAlgorithm algorithm, | |||
int expectedSignatureDigestLength, | |||
byte[] signatureDigestBytes, Class<?> expectedException){ | |||
//初始化一个异常 | |||
Exception actualEx = null; | |||
try { | |||
SignatureDigest signatureDigest = asymmetricCrypto.resolveSignatureDigest(signatureDigestBytes); | |||
assertNotNull(signatureDigest); | |||
assertEquals(algorithm,signatureDigest.getAlgorithm()); | |||
assertEquals(expectedSignatureDigestLength,signatureDigest.getRawDigest().length); | |||
assertArrayEquals(signatureDigestBytes,signatureDigest.toBytes()); | |||
} | |||
catch (Exception e){ | |||
actualEx = e; | |||
} | |||
if (expectedException == null) { | |||
assertNull(actualEx); | |||
} | |||
else { | |||
assertNotNull(actualEx); | |||
assertTrue(expectedException.isAssignableFrom(actualEx.getClass())); | |||
} | |||
} | |||
@Test | |||
public void testTryResolveSignatureDigest() { | |||
} | |||
@Test | |||
public void testRetrievePubKeyBytes() { | |||
AsymmetricCryptography asymmetricCrypto = new AsymmtricCryptographyImpl(); | |||
//test ED25519 | |||
CryptoAlgorithm algorithm = CryptoAlgorithm.ED25519; | |||
CryptoKeyPair keyPair = asymmetricCrypto.generateKeyPair(algorithm); | |||
byte[] expectedPrivKeyBytes = keyPair.getPrivKey().toBytes(); | |||
byte[] expectedPubKeyBytes = keyPair.getPubKey().toBytes(); | |||
byte[] pubKeyBytes = asymmetricCrypto.retrievePubKeyBytes(expectedPrivKeyBytes); | |||
assertArrayEquals(expectedPubKeyBytes,pubKeyBytes); | |||
//test SM2 | |||
algorithm = CryptoAlgorithm.SM2; | |||
keyPair = asymmetricCrypto.generateKeyPair(algorithm); | |||
expectedPrivKeyBytes = keyPair.getPrivKey().toBytes(); | |||
expectedPubKeyBytes = keyPair.getPubKey().toBytes(); | |||
pubKeyBytes = asymmetricCrypto.retrievePubKeyBytes(expectedPrivKeyBytes); | |||
assertArrayEquals(expectedPubKeyBytes,pubKeyBytes); | |||
// //test JNIED25519 | |||
// algorithm = CryptoAlgorithm.JNIED25519; | |||
// | |||
// keyPair = asymmetricCrypto.generateKeyPair(algorithm); | |||
// | |||
// expectedPrivKeyBytes = keyPair.getPrivKey().toBytes(); | |||
// expectedPubKeyBytes = keyPair.getPubKey().toBytes(); | |||
// | |||
// pubKeyBytes = asymmetricCrypto.retrievePubKeyBytes(expectedPrivKeyBytes); | |||
// | |||
// assertArrayEquals(expectedPubKeyBytes,pubKeyBytes); | |||
} | |||
@Test | |||
public void testResolvePubKey() { | |||
AsymmetricCryptography asymmetricCrypto = new AsymmtricCryptographyImpl(); | |||
//test ED25519 | |||
CryptoAlgorithm algorithm = CryptoAlgorithm.ED25519; | |||
CryptoKeyPair keyPair = asymmetricCrypto.generateKeyPair(algorithm); | |||
byte[] pubKeyBytes = keyPair.getPubKey().toBytes(); | |||
verifyResolvePubKey(asymmetricCrypto,algorithm,32,pubKeyBytes,null); | |||
byte[] truncatedPubKeyBytes = new byte[pubKeyBytes.length-2]; | |||
System.arraycopy(pubKeyBytes,0,truncatedPubKeyBytes,0,truncatedPubKeyBytes.length); | |||
verifyResolvePubKey(asymmetricCrypto,algorithm,32,truncatedPubKeyBytes,IllegalArgumentException.class); | |||
byte[] pubKeyBytesWithWrongAlgCode = pubKeyBytes; | |||
pubKeyBytesWithWrongAlgCode[0] = CryptoAlgorithm.SHA256.CODE; | |||
verifyResolvePubKey(asymmetricCrypto,algorithm,32,pubKeyBytesWithWrongAlgCode,IllegalArgumentException.class); | |||
byte[] pubKeyBytesWithWrongKeyType= pubKeyBytes; | |||
pubKeyBytesWithWrongKeyType[1] = PRIV_KEY.CODE; | |||
verifyResolvePubKey(asymmetricCrypto,algorithm,32,pubKeyBytesWithWrongKeyType,IllegalArgumentException.class); | |||
pubKeyBytes = null; | |||
verifyResolvePubKey(asymmetricCrypto,algorithm,32,pubKeyBytes,NullPointerException.class); | |||
//test SM2 | |||
algorithm = CryptoAlgorithm.SM2; | |||
keyPair = asymmetricCrypto.generateKeyPair(algorithm); | |||
pubKeyBytes = keyPair.getPubKey().toBytes(); | |||
verifyResolvePubKey(asymmetricCrypto,algorithm,65,pubKeyBytes,null); | |||
truncatedPubKeyBytes = new byte[pubKeyBytes.length-2]; | |||
System.arraycopy(pubKeyBytes,0,truncatedPubKeyBytes,0,truncatedPubKeyBytes.length); | |||
verifyResolvePubKey(asymmetricCrypto,algorithm,65,truncatedPubKeyBytes,IllegalArgumentException.class); | |||
pubKeyBytesWithWrongAlgCode = pubKeyBytes; | |||
pubKeyBytesWithWrongAlgCode[0] = CryptoAlgorithm.SHA256.CODE; | |||
verifyResolvePubKey(asymmetricCrypto,algorithm,65,pubKeyBytesWithWrongAlgCode,IllegalArgumentException.class); | |||
pubKeyBytesWithWrongKeyType= pubKeyBytes; | |||
pubKeyBytesWithWrongKeyType[1] = PRIV_KEY.CODE; | |||
verifyResolvePubKey(asymmetricCrypto,algorithm,65,pubKeyBytesWithWrongKeyType,IllegalArgumentException.class); | |||
pubKeyBytes = null; | |||
verifyResolvePubKey(asymmetricCrypto,algorithm,65,pubKeyBytes,NullPointerException.class); | |||
// //test JNIED25519 | |||
// algorithm = CryptoAlgorithm.JNIED25519; | |||
// | |||
// keyPair = asymmetricCrypto.generateKeyPair(algorithm); | |||
// | |||
// pubKeyBytes = keyPair.getPubKey().toBytes(); | |||
// verifyResolvePubKey(asymmetricCrypto,algorithm,32,pubKeyBytes,null); | |||
// | |||
// truncatedPubKeyBytes = new byte[pubKeyBytes.length-2]; | |||
// System.arraycopy(pubKeyBytes,0,truncatedPubKeyBytes,0,truncatedPubKeyBytes.length); | |||
// verifyResolvePubKey(asymmetricCrypto,algorithm,32,truncatedPubKeyBytes,IllegalArgumentException.class); | |||
// | |||
// pubKeyBytesWithWrongAlgCode = pubKeyBytes; | |||
// pubKeyBytesWithWrongAlgCode[0] = CryptoAlgorithm.SHA256.CODE; | |||
// verifyResolvePubKey(asymmetricCrypto,algorithm,32,pubKeyBytesWithWrongAlgCode,IllegalArgumentException.class); | |||
// | |||
// pubKeyBytesWithWrongKeyType= pubKeyBytes; | |||
// pubKeyBytesWithWrongKeyType[1] = PRIV_KEY.CODE; | |||
// verifyResolvePubKey(asymmetricCrypto,algorithm,32,pubKeyBytesWithWrongKeyType,IllegalArgumentException.class); | |||
// | |||
// pubKeyBytes = null; | |||
// verifyResolvePubKey(asymmetricCrypto,algorithm,32,pubKeyBytes,NullPointerException.class); | |||
} | |||
private void verifyResolvePubKey(AsymmetricCryptography asymmetricCrypto, CryptoAlgorithm algorithm, | |||
int expectedPubKeyLength, byte[] pubKeyBytes,Class<?> expectedException){ | |||
Exception actualEx = null; | |||
try { | |||
PubKey pubKey = asymmetricCrypto.resolvePubKey(pubKeyBytes); | |||
assertNotNull(pubKey); | |||
assertEquals(algorithm, pubKey.getAlgorithm()); | |||
assertEquals(expectedPubKeyLength, pubKey.getRawKeyBytes().length); | |||
assertArrayEquals(pubKeyBytes, pubKey.toBytes()); | |||
} | |||
catch (Exception e){ | |||
actualEx = e; | |||
} | |||
if (expectedException == null) { | |||
assertNull(actualEx); | |||
} | |||
else { | |||
assertNotNull(actualEx); | |||
assertTrue(expectedException.isAssignableFrom(actualEx.getClass())); | |||
} | |||
} | |||
@Test | |||
public void testTryResolvePubKey() { | |||
} | |||
@Test | |||
public void testResolvePrivKey() { | |||
AsymmetricCryptography asymmetricCrypto = new AsymmtricCryptographyImpl(); | |||
//test ED25519 | |||
CryptoAlgorithm algorithm = CryptoAlgorithm.ED25519; | |||
CryptoKeyPair keyPair = asymmetricCrypto.generateKeyPair(algorithm); | |||
byte[] privKeyBytes = keyPair.getPrivKey().toBytes(); | |||
verifyResolvePrivKey(asymmetricCrypto,algorithm,32,privKeyBytes,null); | |||
byte[] truncatedPrivKeyBytes = new byte[privKeyBytes.length-2]; | |||
System.arraycopy(privKeyBytes,0,truncatedPrivKeyBytes,0,truncatedPrivKeyBytes.length); | |||
verifyResolvePrivKey(asymmetricCrypto,algorithm,32,truncatedPrivKeyBytes,IllegalArgumentException.class); | |||
byte[] privKeyBytesWithWrongAlgCode = privKeyBytes; | |||
privKeyBytesWithWrongAlgCode[0] = CryptoAlgorithm.SHA256.CODE; | |||
verifyResolvePrivKey(asymmetricCrypto,algorithm,32,privKeyBytesWithWrongAlgCode,IllegalArgumentException.class); | |||
byte[] privKeyBytesWithWrongKeyType = privKeyBytes; | |||
privKeyBytesWithWrongKeyType[1] = PUB_KEY.CODE; | |||
verifyResolvePrivKey(asymmetricCrypto,algorithm,32,privKeyBytesWithWrongKeyType,IllegalArgumentException.class); | |||
privKeyBytes = null; | |||
verifyResolvePrivKey(asymmetricCrypto,algorithm,32,privKeyBytes,NullPointerException.class); | |||
//test SM2 | |||
algorithm = CryptoAlgorithm.SM2; | |||
keyPair = asymmetricCrypto.generateKeyPair(algorithm); | |||
privKeyBytes = keyPair.getPrivKey().toBytes(); | |||
verifyResolvePrivKey(asymmetricCrypto,algorithm,32,privKeyBytes,null); | |||
truncatedPrivKeyBytes = new byte[privKeyBytes.length-2]; | |||
System.arraycopy(privKeyBytes,0,truncatedPrivKeyBytes,0,truncatedPrivKeyBytes.length); | |||
verifyResolvePrivKey(asymmetricCrypto,algorithm,32,truncatedPrivKeyBytes,IllegalArgumentException.class); | |||
privKeyBytesWithWrongAlgCode = privKeyBytes; | |||
privKeyBytesWithWrongAlgCode[0] = CryptoAlgorithm.SHA256.CODE; | |||
verifyResolvePrivKey(asymmetricCrypto,algorithm,32,privKeyBytesWithWrongAlgCode,IllegalArgumentException.class); | |||
privKeyBytesWithWrongKeyType = privKeyBytes; | |||
privKeyBytesWithWrongKeyType[1] = PUB_KEY.CODE; | |||
verifyResolvePrivKey(asymmetricCrypto,algorithm,32,privKeyBytesWithWrongKeyType,IllegalArgumentException.class); | |||
privKeyBytes = null; | |||
verifyResolvePrivKey(asymmetricCrypto,algorithm,32,privKeyBytes,NullPointerException.class); | |||
// //test JNIED25519 | |||
// algorithm = CryptoAlgorithm.JNIED25519; | |||
// | |||
// keyPair = asymmetricCrypto.generateKeyPair(algorithm); | |||
// | |||
// privKeyBytes = keyPair.getPrivKey().toBytes(); | |||
// verifyResolvePrivKey(asymmetricCrypto,algorithm,32,privKeyBytes,null); | |||
// | |||
// truncatedPrivKeyBytes = new byte[privKeyBytes.length-2]; | |||
// System.arraycopy(privKeyBytes,0,truncatedPrivKeyBytes,0,truncatedPrivKeyBytes.length); | |||
// verifyResolvePrivKey(asymmetricCrypto,algorithm,32,truncatedPrivKeyBytes,IllegalArgumentException.class); | |||
// | |||
// privKeyBytesWithWrongAlgCode = privKeyBytes; | |||
// privKeyBytesWithWrongAlgCode[0] = CryptoAlgorithm.SHA256.CODE; | |||
// verifyResolvePrivKey(asymmetricCrypto,algorithm,32,privKeyBytesWithWrongAlgCode,IllegalArgumentException.class); | |||
// | |||
// privKeyBytesWithWrongKeyType = privKeyBytes; | |||
// privKeyBytesWithWrongKeyType[1] = PUB_KEY.CODE; | |||
// verifyResolvePrivKey(asymmetricCrypto,algorithm,32,privKeyBytesWithWrongKeyType,IllegalArgumentException.class); | |||
// | |||
// privKeyBytes = null; | |||
// verifyResolvePrivKey(asymmetricCrypto,algorithm,32,privKeyBytes,NullPointerException.class); | |||
} | |||
private void verifyResolvePrivKey(AsymmetricCryptography asymmetricCrypto, CryptoAlgorithm algorithm, | |||
int expectedPrivKeyLength, byte[] privKeyBytes,Class<?> expectedException){ | |||
Exception actualEx = null; | |||
try { | |||
PrivKey privKey = asymmetricCrypto.resolvePrivKey(privKeyBytes); | |||
assertNotNull(privKey); | |||
assertEquals(algorithm, privKey.getAlgorithm()); | |||
assertEquals(expectedPrivKeyLength, privKey.getRawKeyBytes().length); | |||
assertArrayEquals(privKeyBytes, privKey.toBytes()); | |||
} | |||
catch (Exception e){ | |||
actualEx = e; | |||
} | |||
if (expectedException == null) { | |||
assertNull(actualEx); | |||
} | |||
else { | |||
assertNotNull(actualEx); | |||
assertTrue(expectedException.isAssignableFrom(actualEx.getClass())); | |||
} | |||
} | |||
@Test | |||
public void testTryResolvePrivKey() { | |||
} | |||
} |
@@ -0,0 +1,333 @@ | |||
package test.com.jd.blockchain.crypto.hash; | |||
import static org.junit.Assert.*; | |||
import java.util.Random; | |||
import com.jd.blockchain.crypto.smutils.hash.SM3Utils; | |||
import com.jd.blockchain.utils.io.BytesUtils; | |||
import com.jd.blockchain.utils.security.RipeMD160Utils; | |||
import com.jd.blockchain.utils.security.ShaUtils; | |||
import org.junit.Test; | |||
import com.jd.blockchain.crypto.CryptoAlgorithm; | |||
import com.jd.blockchain.crypto.hash.HashCryptography; | |||
import com.jd.blockchain.crypto.hash.HashDigest; | |||
import com.jd.blockchain.crypto.hash.HashFunction; | |||
import com.jd.blockchain.crypto.impl.HashCryptographyImpl; | |||
public class HashCryptographyImplTest { | |||
@Test | |||
public void testGetFunction() { | |||
HashCryptography hashCrypto = new HashCryptographyImpl(); | |||
Random rand = new Random(); | |||
// test SHA256 | |||
CryptoAlgorithm algorithm = CryptoAlgorithm.SHA256; | |||
byte[] data = new byte[256]; | |||
rand.nextBytes(data); | |||
verifyGetFunction(hashCrypto, algorithm, data, 256 / 8,null); | |||
data = new byte[0]; | |||
verifyGetFunction(hashCrypto, algorithm, data, 256 / 8,null); | |||
data = new byte[1056]; | |||
rand.nextBytes(data); | |||
verifyGetFunction(hashCrypto, algorithm, data, 256 / 8,null); | |||
data = null; | |||
verifyGetFunction(hashCrypto, algorithm, data, 256 / 8,NullPointerException.class); | |||
// test RIPEMD160 | |||
algorithm = CryptoAlgorithm.RIPEMD160; | |||
data=new byte[256]; | |||
rand.nextBytes(data); | |||
verifyGetFunction(hashCrypto, algorithm, data, 160 / 8,null); | |||
data = new byte[0]; | |||
verifyGetFunction(hashCrypto, algorithm, data, 160/ 8,null); | |||
data = new byte[1056]; | |||
rand.nextBytes(data); | |||
verifyGetFunction(hashCrypto, algorithm, data, 160 / 8,null); | |||
data = null; | |||
verifyGetFunction(hashCrypto, algorithm, data, 160 / 8,NullPointerException.class); | |||
// test SM3 | |||
algorithm = CryptoAlgorithm.SM3; | |||
data = new byte[256]; | |||
rand.nextBytes(data); | |||
verifyGetFunction(hashCrypto, algorithm, data, 256 / 8,null); | |||
data = new byte[0]; | |||
verifyGetFunction(hashCrypto, algorithm, data, 256 / 8,null); | |||
data = new byte[1056]; | |||
rand.nextBytes(data); | |||
verifyGetFunction(hashCrypto, algorithm, data, 256 / 8,null); | |||
data = null; | |||
verifyGetFunction(hashCrypto, algorithm, data, 256 / 8,NullPointerException.class); | |||
// test AES | |||
data = new byte[0]; | |||
algorithm = CryptoAlgorithm.AES; | |||
verifyGetFunction(hashCrypto, algorithm, data, 256 / 8,IllegalArgumentException.class); | |||
// // test JNISHA256 | |||
// algorithm = CryptoAlgorithm.JNISHA256; | |||
// data = new byte[256]; | |||
// rand.nextBytes(data); | |||
// verifyGetFunction(hashCrypto, algorithm, data, 256 / 8,null); | |||
// | |||
// data = new byte[0]; | |||
// verifyGetFunction(hashCrypto, algorithm, data, 256 / 8,null); | |||
// | |||
// data = new byte[1056]; | |||
// rand.nextBytes(data); | |||
// verifyGetFunction(hashCrypto, algorithm, data, 256 / 8,null); | |||
// | |||
// data = null; | |||
// verifyGetFunction(hashCrypto, algorithm, data, 256 / 8,IllegalArgumentException.class); | |||
// | |||
// // test JNIRIPEMD160 | |||
// algorithm = CryptoAlgorithm.JNIRIPEMD160; | |||
// data=new byte[256]; | |||
// rand.nextBytes(data); | |||
// verifyGetFunction(hashCrypto, algorithm, data, 160 / 8,null); | |||
// | |||
// data = new byte[0]; | |||
// verifyGetFunction(hashCrypto, algorithm, data, 160/ 8,null); | |||
// | |||
// data = new byte[1056]; | |||
// rand.nextBytes(data); | |||
// verifyGetFunction(hashCrypto, algorithm, data, 160 / 8,null); | |||
// | |||
// data = null; | |||
// verifyGetFunction(hashCrypto, algorithm, data, 160 / 8,IllegalArgumentException.class); | |||
} | |||
private void verifyGetFunction(HashCryptography hashCrypto, CryptoAlgorithm algorithm, byte[] data, | |||
int expectedRawBytes,Class<?> expectedException) { | |||
Exception actualEx = null; | |||
try { | |||
HashFunction hf = hashCrypto.getFunction(algorithm); | |||
assertNotNull(hf); | |||
HashDigest hd = hf.hash(data); | |||
assertEquals(algorithm, hd.getAlgorithm()); | |||
assertEquals(expectedRawBytes, hd.getRawDigest().length); | |||
// verify encoding; | |||
byte[] encodedHash = hd.toBytes(); | |||
assertEquals(expectedRawBytes + 1, encodedHash.length); | |||
assertEquals(algorithm.CODE, encodedHash[0]); | |||
//verify equals | |||
assertEquals(true, hd.equals(hf.hash(data))); | |||
//verify verify | |||
assertTrue( hf.verify(hd, data)); | |||
} catch (Exception e) { | |||
actualEx = e; | |||
} | |||
if(expectedException==null){ | |||
assertNull(actualEx); | |||
} | |||
else { | |||
assertNotNull(actualEx); | |||
assertTrue(expectedException.isAssignableFrom(actualEx.getClass())); | |||
} | |||
} | |||
@Test | |||
public void testVerifyHashDigestByteArray() { | |||
HashCryptography hashCrypto = new HashCryptographyImpl(); | |||
//test SHA256 | |||
byte[] data=new byte[256]; | |||
Random rand = new Random(); | |||
rand.nextBytes(data); | |||
CryptoAlgorithm algorithm=CryptoAlgorithm.SHA256; | |||
verifyHashDigestByteArray(hashCrypto,algorithm,data,null); | |||
data=null; | |||
verifyHashDigestByteArray(hashCrypto,algorithm,data,NullPointerException.class); | |||
//test RIPEMD160 | |||
algorithm=CryptoAlgorithm.RIPEMD160; | |||
data=new byte[896]; | |||
rand.nextBytes(data); | |||
verifyHashDigestByteArray(hashCrypto,algorithm,data,null); | |||
data=null; | |||
verifyHashDigestByteArray(hashCrypto,algorithm,data,NullPointerException.class); | |||
//test SM3 | |||
algorithm=CryptoAlgorithm.SM3; | |||
data=new byte[896]; | |||
rand.nextBytes(data); | |||
verifyHashDigestByteArray(hashCrypto,algorithm,data,null); | |||
data=null; | |||
verifyHashDigestByteArray(hashCrypto,algorithm,data,NullPointerException.class); | |||
//test AES | |||
algorithm=CryptoAlgorithm.AES; | |||
data=new byte[277]; | |||
rand.nextBytes(data); | |||
verifyHashDigestByteArray(hashCrypto,algorithm,data,IllegalArgumentException.class); | |||
// //test JNISHA256 | |||
// data=new byte[256]; | |||
// rand = new Random(); | |||
// rand.nextBytes(data); | |||
// algorithm=CryptoAlgorithm.JNISHA256; | |||
// verifyHashDigestByteArray(hashCrypto,algorithm,data,null); | |||
// data=null; | |||
// verifyHashDigestByteArray(hashCrypto,algorithm,data,IllegalArgumentException.class); | |||
// | |||
// //test JNIRIPEMD160 | |||
// algorithm=CryptoAlgorithm.JNIRIPEMD160; | |||
// data=new byte[896]; | |||
// rand.nextBytes(data); | |||
// verifyHashDigestByteArray(hashCrypto,algorithm,data,null); | |||
// data=null; | |||
// verifyHashDigestByteArray(hashCrypto,algorithm,data,IllegalArgumentException.class); | |||
} | |||
private void verifyHashDigestByteArray(HashCryptography hashCrypto,CryptoAlgorithm algorithm,byte[] data,Class<?> expectedException){ | |||
Exception actualEx=null; | |||
try { | |||
HashFunction hf = hashCrypto.getFunction(algorithm); | |||
assertNotNull(hf); | |||
HashDigest hd = hf.hash(data); | |||
hashCrypto.verify(hd,data); | |||
}catch (Exception e) | |||
{ | |||
actualEx=e; | |||
} | |||
if (expectedException==null) | |||
{ | |||
assertNull(actualEx); | |||
} | |||
else{ | |||
assertNotNull(actualEx); | |||
assertTrue(expectedException.isAssignableFrom(actualEx.getClass())); | |||
} | |||
} | |||
@Test | |||
public void testResolveHashDigest() { | |||
Random rand = new Random(); | |||
HashCryptography hashCrypto = new HashCryptographyImpl(); | |||
//test SHA256 | |||
CryptoAlgorithm algorithm = CryptoAlgorithm.SHA256; | |||
byte[] data = new byte[256]; | |||
rand.nextBytes(data); | |||
byte[] hashDigestBytes = hashCrypto.getFunction(algorithm).hash(data).toBytes(); | |||
verifyResolveHashDigest(algorithm, hashCrypto,hashDigestBytes,32+1,null); | |||
byte[] truncatedHashDigestBytes = new byte[hashDigestBytes.length-2]; | |||
System.arraycopy(hashDigestBytes,0,truncatedHashDigestBytes,0,truncatedHashDigestBytes.length); | |||
verifyResolveHashDigest(algorithm, hashCrypto,truncatedHashDigestBytes,32+1,IllegalArgumentException.class); | |||
hashDigestBytes = null; | |||
verifyResolveHashDigest(algorithm, hashCrypto,hashDigestBytes,32+1,NullPointerException.class); | |||
//test RIPEMD160 | |||
algorithm = CryptoAlgorithm.RIPEMD160; | |||
data = new byte[256]; | |||
rand.nextBytes(data); | |||
hashDigestBytes = hashCrypto.getFunction(algorithm).hash(data).toBytes(); | |||
verifyResolveHashDigest(algorithm, hashCrypto,hashDigestBytes,20+1,null); | |||
truncatedHashDigestBytes = new byte[hashDigestBytes.length-2]; | |||
System.arraycopy(hashDigestBytes,0,truncatedHashDigestBytes,0,truncatedHashDigestBytes.length); | |||
verifyResolveHashDigest(algorithm, hashCrypto,truncatedHashDigestBytes,20+1,IllegalArgumentException.class); | |||
hashDigestBytes = null; | |||
verifyResolveHashDigest(algorithm, hashCrypto,hashDigestBytes,20+1,NullPointerException.class); | |||
//test SM3 | |||
algorithm = CryptoAlgorithm.SM3; | |||
data = new byte[256]; | |||
rand.nextBytes(data); | |||
hashDigestBytes = hashCrypto.getFunction(algorithm).hash(data).toBytes(); | |||
verifyResolveHashDigest(algorithm, hashCrypto,hashDigestBytes,32+1,null); | |||
truncatedHashDigestBytes = new byte[hashDigestBytes.length-2]; | |||
System.arraycopy(hashDigestBytes,0,truncatedHashDigestBytes,0,truncatedHashDigestBytes.length); | |||
verifyResolveHashDigest(algorithm, hashCrypto,truncatedHashDigestBytes,32+1,IllegalArgumentException.class); | |||
hashDigestBytes = null; | |||
verifyResolveHashDigest(algorithm, hashCrypto,hashDigestBytes,32+1,NullPointerException.class); | |||
// //test JNISHA256 | |||
// algorithm = CryptoAlgorithm.JNISHA256; | |||
// data = new byte[256]; | |||
// rand.nextBytes(data); | |||
// hashDigestBytes = hashCrypto.getFunction(algorithm).hash(data).toBytes(); | |||
// verifyResolveHashDigest(algorithm, hashCrypto,hashDigestBytes,32+1,null); | |||
// | |||
// truncatedHashDigestBytes = new byte[hashDigestBytes.length-2]; | |||
// System.arraycopy(hashDigestBytes,0,truncatedHashDigestBytes,0,truncatedHashDigestBytes.length); | |||
// verifyResolveHashDigest(algorithm, hashCrypto,truncatedHashDigestBytes,32+1,IllegalArgumentException.class); | |||
// | |||
// hashDigestBytes = null; | |||
// verifyResolveHashDigest(algorithm, hashCrypto,hashDigestBytes,32+1,NullPointerException.class); | |||
// | |||
// //test JNIRIPEMD160 | |||
// algorithm = CryptoAlgorithm.JNIRIPEMD160; | |||
// data = new byte[256]; | |||
// rand.nextBytes(data); | |||
// hashDigestBytes = hashCrypto.getFunction(algorithm).hash(data).toBytes(); | |||
// verifyResolveHashDigest(algorithm, hashCrypto,hashDigestBytes,20+1,null); | |||
// | |||
// truncatedHashDigestBytes = new byte[hashDigestBytes.length-2]; | |||
// System.arraycopy(hashDigestBytes,0,truncatedHashDigestBytes,0,truncatedHashDigestBytes.length); | |||
// verifyResolveHashDigest(algorithm, hashCrypto,truncatedHashDigestBytes,20+1,IllegalArgumentException.class); | |||
// | |||
// hashDigestBytes = null; | |||
// verifyResolveHashDigest(algorithm, hashCrypto,hashDigestBytes,20+1,NullPointerException.class); | |||
} | |||
private void verifyResolveHashDigest(CryptoAlgorithm algorithm,HashCryptography | |||
hashCrypto,byte[] hashDigestBytes,int expectedLength,Class<?>expectedException){ | |||
Exception actualEx=null; | |||
try { | |||
HashDigest hashDigest=hashCrypto.resolveHashDigest(hashDigestBytes); | |||
assertNotNull(hashDigest); | |||
assertEquals(algorithm,hashDigest.getAlgorithm()); | |||
byte[] algBytes = new byte[1]; | |||
algBytes[0] = algorithm.CODE; | |||
assertArrayEquals(hashDigestBytes,BytesUtils.concat(algBytes,hashDigest.getRawDigest())); | |||
assertEquals(expectedLength,hashDigestBytes.length); | |||
}catch (Exception e) | |||
{ | |||
actualEx = e; | |||
} | |||
if (expectedException==null) | |||
{ | |||
assertNull(actualEx); | |||
} | |||
else { | |||
assertNotNull(actualEx); | |||
assertTrue(expectedException.isAssignableFrom(actualEx.getClass())); | |||
} | |||
} | |||
} |
@@ -0,0 +1,123 @@ | |||
//package test.com.jd.blockchain.crypto.jniutils; | |||
// | |||
//import com.jd.blockchain.crypto.jniutils.asymmetric.JNIED25519Utils; | |||
// | |||
// | |||
//public class JNIED25519UtilsTest { | |||
// | |||
// /* Program entry function */ | |||
// public static void main(String args[]) { | |||
// | |||
// byte[] msg = "abc".getBytes(); | |||
// int i; | |||
// int j; | |||
// int count = 10000; | |||
// | |||
// long startTS; | |||
// long elapsedTS; | |||
// | |||
// byte[] privKey = new byte[32]; | |||
// byte[] pubKey = new byte[32]; | |||
// byte[] signature; | |||
// | |||
// | |||
// JNIED25519Utils ed25519 = new JNIED25519Utils(); | |||
// | |||
// System.out.println("=================== Key Generation test ==================="); | |||
// ed25519.generateKeyPair(privKey,pubKey); | |||
// System.out.println("Private Key: "); | |||
// for(i = 0; i < privKey.length; i++) { | |||
// System.out.print(privKey[i] + " "); | |||
// if((i+1)%8 == 0) | |||
// System.out.println(); | |||
// } | |||
// System.out.println(); | |||
// System.out.println("Public Key: "); | |||
// for(i = 0; i < pubKey.length; i++) { | |||
// System.out.print(pubKey[i] + " "); | |||
// if((i+1)%8 == 0) | |||
// System.out.println(); | |||
// } | |||
// System.out.println(); | |||
// | |||
// System.out.println("=================== Public Key Retrieval test ==================="); | |||
// byte[] pk; | |||
// pk = ed25519.getPubKey(privKey); | |||
// System.out.println("Retrieved Public Key: "); | |||
// for(i = 0; i < pk.length; i++) { | |||
// System.out.print(pk[i] + " "); | |||
// if((i+1)%8 == 0) | |||
// System.out.println(); | |||
// } | |||
// System.out.println(); | |||
// | |||
// System.out.println("=================== Signing test ==================="); | |||
// signature = ed25519.sign(msg,privKey,pubKey); | |||
// System.out.println("Signature: "); | |||
// for(i = 0; i < signature.length; i++) { | |||
// System.out.print(signature[i] + " "); | |||
// if((i+1)%8 == 0) | |||
// System.out.println(); | |||
// } | |||
// System.out.println(); | |||
// | |||
// System.out.println("=================== Verifying test ==================="); | |||
// if (ed25519.verify(msg,pubKey,signature)) | |||
// System.out.println("valid signature"); | |||
// else System.out.println("invalid signature"); | |||
// | |||
// System.out.println("=================== Do ED25519 Key Pair Generation Test ==================="); | |||
// | |||
// | |||
// for (j = 0; j < 5; j++) { | |||
// System.out.println("------------- round[" + j + "] --------------"); | |||
// startTS = System.currentTimeMillis(); | |||
// for (i = 0; i < count; i++) { | |||
// ed25519.generateKeyPair(privKey,pubKey); | |||
// } | |||
// elapsedTS = System.currentTimeMillis() - startTS; | |||
// System.out.println(String.format("ED25519 Key Pair Generation: Count=%s; Elapsed Times=%s; TPS=%.2f", count, elapsedTS, | |||
// (count * 1000.00D) / elapsedTS)); | |||
// } | |||
// System.out.println(); | |||
// | |||
// System.out.println("=================== Do ED25519 Public Key Retrieval Test ==================="); | |||
// for (j = 0; j < 5; j++) { | |||
// System.out.println("------------- round[" + j + "] --------------"); | |||
// startTS = System.currentTimeMillis(); | |||
// for (i = 0; i < count; i++) { | |||
// ed25519.getPubKey(privKey); | |||
// } | |||
// elapsedTS = System.currentTimeMillis() - startTS; | |||
// System.out.println(String.format("ED25519 Public Key Retrieval: Count=%s; Elapsed Times=%s; TPS=%.2f", count, elapsedTS, | |||
// (count * 1000.00D) / elapsedTS)); | |||
// } | |||
// System.out.println(); | |||
// | |||
// System.out.println("=================== Do ED25519 Signing Test ==================="); | |||
// for (j = 0; j < 5; j++) { | |||
// System.out.println("------------- round[" + j + "] --------------"); | |||
// startTS = System.currentTimeMillis(); | |||
// for (i = 0; i < count; i++) { | |||
// ed25519.sign(msg,privKey,pubKey); | |||
// } | |||
// elapsedTS = System.currentTimeMillis() - startTS; | |||
// System.out.println(String.format("ED25519 Signing: Count=%s; Elapsed Times=%s; TPS=%.2f", count, elapsedTS, | |||
// (count * 1000.00D) / elapsedTS)); | |||
// } | |||
// System.out.println(); | |||
// | |||
// System.out.println("=================== Do ED25519 Verifying Test ==================="); | |||
// for (j = 0; j < 5; j++) { | |||
// System.out.println("------------- round[" + j + "] --------------"); | |||
// startTS = System.currentTimeMillis(); | |||
// for (i = 0; i < count; i++) { | |||
// ed25519.verify(msg,pubKey,signature); | |||
// } | |||
// elapsedTS = System.currentTimeMillis() - startTS; | |||
// System.out.println(String.format("ED25519 Verifying: Count=%s; Elapsed Times=%s; TPS=%.2f", count, elapsedTS, | |||
// (count * 1000.00D) / elapsedTS)); | |||
// } | |||
// System.out.println(); | |||
// } | |||
//} |
@@ -0,0 +1,111 @@ | |||
//package test.com.jd.blockchain.crypto.jniutils; | |||
// | |||
//import com.jd.blockchain.crypto.jniutils.hash.JNIMBSHA256Utils; | |||
// | |||
//public class JNIMBSHA256UtilsTest { | |||
// /* Program entry function */ | |||
// public static void main(String args[]) { | |||
// | |||
// String osName = System.getProperty("os.name").toLowerCase(); | |||
// | |||
// if (! osName.contains("linux")) { | |||
// return ; | |||
// } | |||
// | |||
// byte[] array1 = "abc".getBytes(); | |||
// byte[] array2 = "abcd".getBytes(); | |||
// byte[] array3 = "abcde".getBytes(); | |||
// byte[] array4 = "abcdef".getBytes(); | |||
// | |||
// byte[][] arrays = {array1,array2,array3,array4}; | |||
// JNIMBSHA256Utils mbsha256 = new JNIMBSHA256Utils(); | |||
// byte[][] results = mbsha256.multiBufferHash(arrays); | |||
// | |||
// System.out.println("JAVA to C : "); | |||
// for (int i = 0; i < arrays.length; i++) { | |||
// for (int j = 0; j < arrays[i].length; j++) { | |||
// System.out.print(arrays[i][j] + " "); | |||
// } | |||
// System.out.println(); | |||
// } | |||
// | |||
// System.out.println(); | |||
// | |||
// System.out.println("C to JAVA : "); | |||
// for (int i = 0; i < results.length; i++) { | |||
// for (int j = 0; j < results[i].length; j++) { | |||
// System.out.print(results[i][j] + " "); | |||
// } | |||
// System.out.println(); | |||
// } | |||
// | |||
// System.out.println(); | |||
// | |||
// String str = "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"; | |||
// byte[] array = str.getBytes(); | |||
// | |||
// | |||
// int count = 1000000; | |||
// | |||
// | |||
// byte[][] arraysx4 = {array,array,array,array}; | |||
// byte[][] arraysx8 = {array,array,array,array,array,array,array,array}; | |||
// byte[][] arraysx16 = {array,array,array,array,array,array,array,array,array,array,array,array,array,array,array,array}; | |||
// byte[][] arraysx32 = {array,array,array,array,array,array,array,array,array,array,array,array,array,array,array,array,array,array,array,array,array,array,array,array,array,array,array,array,array,array,array,array}; | |||
// | |||
// | |||
// System.out.println("=================== do MBSHA256 hash test in x4==================="); | |||
// for (int r = 0; r < 5; r++) { | |||
// System.out.println("------------- round[" + r + "] --------------"); | |||
// long startTS = System.currentTimeMillis(); | |||
// for (int i = 0; i < count; i++) { | |||
// mbsha256.multiBufferHash(arraysx4); | |||
// } | |||
// long elapsedTS = System.currentTimeMillis() - startTS; | |||
// System.out.println(String.format("SHA256 hashing Count=%s; Elapsed Times=%s; KBPS=%.2f; Total KBPS=%.2f", count, elapsedTS, | |||
// (count * 1000.00D) / elapsedTS, (count * 1000.00D) / elapsedTS*4)); | |||
// } | |||
// System.out.println(); | |||
// System.out.println(); | |||
// | |||
// System.out.println("=================== do MBSHA256 hash test in x8==================="); | |||
// for (int r = 0; r < 5; r++) { | |||
// System.out.println("------------- round[" + r + "] --------------"); | |||
// long startTS = System.currentTimeMillis(); | |||
// for (int i = 0; i < count; i++) { | |||
// mbsha256.multiBufferHash(arraysx8); | |||
// } | |||
// long elapsedTS = System.currentTimeMillis() - startTS; | |||
// System.out.println(String.format("SHA256 hashing Count=%s; Elapsed Times=%s; KBPS=%.2f; Total KBPS=%.2f", count, elapsedTS, | |||
// (count * 1000.00D) / elapsedTS, (count * 1000.00D) / elapsedTS*8)); | |||
// } | |||
// System.out.println(); | |||
// System.out.println(); | |||
// | |||
// System.out.println("=================== do MBSHA256 hash test in x16==================="); | |||
// for (int r = 0; r < 5; r++) { | |||
// System.out.println("------------- round[" + r + "] --------------"); | |||
// long startTS = System.currentTimeMillis(); | |||
// for (int i = 0; i < count; i++) { | |||
// mbsha256.multiBufferHash(arraysx16); | |||
// } | |||
// long elapsedTS = System.currentTimeMillis() - startTS; | |||
// System.out.println(String.format("SHA256 hashing Count=%s; Elapsed Times=%s; KBPS=%.2f; Total KBPS=%.2f", count, elapsedTS, | |||
// (count * 1000.00D) / elapsedTS, (count * 1000.00D) / elapsedTS*16)); | |||
// } | |||
// System.out.println(); | |||
// System.out.println(); | |||
// | |||
// System.out.println("=================== do MBSHA256 hash test in x32==================="); | |||
// for (int r = 0; r < 5; r++) { | |||
// System.out.println("------------- round[" + r + "] --------------"); | |||
// long startTS = System.currentTimeMillis(); | |||
// for (int i = 0; i < count; i++) { | |||
// mbsha256.multiBufferHash(arraysx32); | |||
// } | |||
// long elapsedTS = System.currentTimeMillis() - startTS; | |||
// System.out.println(String.format("SHA256 hashing Count=%s; Elapsed Times=%s; KBPS=%.2f; Total KBPS=%.2f", count, elapsedTS, | |||
// (count * 1000.00D) / elapsedTS, (count * 1000.00D) / elapsedTS*32)); | |||
// } | |||
// } | |||
//} |
@@ -0,0 +1,41 @@ | |||
//package test.com.jd.blockchain.crypto.jniutils; | |||
// | |||
//import com.jd.blockchain.crypto.jniutils.hash.JNIRIPEMD160Utils; | |||
// | |||
//public class JNIRIPEMD160UtilsTest { | |||
// | |||
// /* Program entry function */ | |||
// public static void main(String args[]) { | |||
// byte[] array1 = "abc".getBytes(); | |||
// byte[] array2; | |||
// JNIRIPEMD160Utils ripemd160 = new JNIRIPEMD160Utils(); | |||
// array2 = ripemd160.hash(array1); | |||
// | |||
// System.out.print("JAVA to C : "); | |||
// for (byte anArray1 : array1) { | |||
// System.out.print(anArray1 + " "); | |||
// } | |||
// System.out.println(); | |||
// System.out.print("C to JAVA : "); | |||
// for (byte anArray2 : array2) { | |||
// System.out.print(anArray2 + " "); | |||
// } | |||
// System.out.println(); | |||
// | |||
// String str = "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"; | |||
// byte[] array = str.getBytes(); | |||
// int count = 1000000; | |||
// | |||
// System.out.println("=================== do RIPEMD160 hash test ==================="); | |||
// for (int r = 0; r < 5; r++) { | |||
// System.out.println("------------- round[" + r + "] --------------"); | |||
// long startTS = System.currentTimeMillis(); | |||
// for (int i = 0; i < count; i++) { | |||
// ripemd160.hash(array); | |||
// } | |||
// long elapsedTS = System.currentTimeMillis() - startTS; | |||
// System.out.println(String.format("RIPEMD160 hashing Count=%s; Elapsed Times=%s; KBPS=%.2f", count, elapsedTS, | |||
// (count * 1000.00D) / elapsedTS)); | |||
// } | |||
// } | |||
//} |
@@ -0,0 +1,41 @@ | |||
//package test.com.jd.blockchain.crypto.jniutils; | |||
// | |||
//import com.jd.blockchain.crypto.jniutils.hash.JNISHA256Utils; | |||
// | |||
//public class JNISHA256UtilsTest { | |||
// | |||
// /* Program entry function */ | |||
// public static void main(String args[]) { | |||
// byte[] array1 = "abc".getBytes(); | |||
// byte[] array2; | |||
// JNISHA256Utils sha256 = new JNISHA256Utils(); | |||
// array2 = sha256.hash(array1); | |||
// System.out.print("JAVA to C : "); | |||
// for (byte anArray1 : array1) { | |||
// System.out.print(anArray1 + " "); | |||
// } | |||
// System.out.println(); | |||
// System.out.print("C to JAVA : "); | |||
// for (byte anArray2 : array2) { | |||
// System.out.print(anArray2 + " "); | |||
// } | |||
// System.out.println(); | |||
// | |||
// | |||
// String str = "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"; | |||
// byte[] array = str.getBytes(); | |||
// int count = 1000000; | |||
// | |||
// System.out.println("=================== do SHA256 hash test ==================="); | |||
// for (int r = 0; r < 5; r++) { | |||
// System.out.println("------------- round[" + r + "] --------------"); | |||
// long startTS = System.currentTimeMillis(); | |||
// for (int i = 0; i < count; i++) { | |||
// sha256.hash(array); | |||
// } | |||
// long elapsedTS = System.currentTimeMillis() - startTS; | |||
// System.out.println(String.format("SHA256 hashing Count=%s; Elapsed Times=%s; KBPS=%.2f", count, elapsedTS, | |||
// (count * 1000.00D) / elapsedTS)); | |||
// } | |||
// } | |||
//} |
@@ -1,28 +1,30 @@ | |||
#网关的HTTP服务地址; | |||
http.host=127.0.0.1 | |||
http.host=0.0.0.0 | |||
#网关的HTTP服务端口; | |||
http.port=8081 | |||
#网关的HTTP服务上下文路径,可选; | |||
#http.context-path= | |||
#共识节点的服务地址; | |||
#共识节点的服务地址(与该网关节点连接的Peer节点的IP地址); | |||
peer.host=127.0.0.1 | |||
#共识节点的服务端口; | |||
#共识节点的服务端口(与该网关节点连接的Peer节点的端口); | |||
peer.port=7080 | |||
#共识节点的服务是否启用安全证书; | |||
peer.secure=false | |||
#共识节点的服务提供解析器 | |||
#BftSmart共识Provider:com.jd.blockchain.consensus.bftsmart.BftsmartConsensusProvider | |||
#简单消息共识Provider:com.jd.blockchain.consensus.mq.MsgQueueConsensusProvider | |||
peer.providers=com.jd.blockchain.consensus.bftsmart.BftsmartConsensusProvider | |||
#数据检索服务对应URL | |||
#数据检索服务对应URL,格式:http://{ip}:{port},例如:http://127.0.0.1:10001 | |||
#若该值不配置或配置不正确,则浏览器模糊查询部分无法正常显示 | |||
data.retrieval.url=http://192.168.1.1:10001 | |||
data.retrieval.url=http://127.0.0.1:10001 | |||
#默认公钥的内容(Base58编码数据); | |||
keys.default.pubkey=endPsK36koyFr1D245Sa9j83vt6pZUdFBJoJRB3xAsWM6cwhRbna | |||
keys.default.pubkey= | |||
#默认私钥的路径;在 pk-path 和 pk 之间必须设置其一; | |||
keys.default.privkey-path= | |||
#默认私钥的内容(加密的Base58编码数据);在 pk-path 和 pk 之间必须设置其一; | |||
keys.default.privkey=177gjsj5PHeCpbAtJE7qnbmhuZMHAEKuMsd45zHkv8F8AWBvTBbff8yRKdCyT3kwrmAjSnY | |||
keys.default.privkey= | |||
#默认私钥的解码密码; | |||
keys.default.privkey-password=DYu3G8aGTMBW1WrTw76zxQJQU4DHLw9MLyy7peG4LKkY | |||
keys.default.privkey-password= |
@@ -5,5 +5,5 @@ GATEWAY=$(ls $HOME/lib | grep deployment-gateway-) | |||
if [ ! -n "$GATEWAY" ]; then | |||
echo "GateWay Is Null !!!" | |||
else | |||
nohup java -jar -server $HOME/lib/$GATEWAY -c $HOME/config/gateway.conf -sp $HOME/config/application.properties $* > gw.out 2>&1 & | |||
nohup java -jar -server $HOME/lib/$GATEWAY -c $HOME/config/gateway.conf $* > gw.out 2>&1 & | |||
fi |
@@ -28,7 +28,7 @@ system.block.maxdelay=500 | |||
###### #Consensus Participant0 ###### | |||
############################################ | |||
system.server.0.pubkey=endPsK36koyFr1D245Sa9j83vt6pZUdFBJoJRB3xAsWM6cwhRbna | |||
system.server.0.pubkey= | |||
system.server.0.network.host=127.0.0.1 | |||
system.server.0.network.port=16000 | |||
system.server.0.network.secure=false | |||
@@ -37,7 +37,7 @@ system.server.0.network.secure=false | |||
###### #Consensus Participant1 ###### | |||
############################################ | |||
system.server.1.pubkey=endPsK36sC5JdPCDPDAXUwZtS3sxEmqEhFcC4whayAsTTh8Z6eoZ | |||
system.server.1.pubkey= | |||
system.server.1.network.host=127.0.0.1 | |||
system.server.1.network.port=16010 | |||
system.server.1.network.secure=false | |||
@@ -46,7 +46,7 @@ system.server.1.network.secure=false | |||
###### #Consensus Participant2 ###### | |||
############################################ | |||
system.server.2.pubkey=endPsK36jEG281HMHeh6oSqzqLkT95DTnCM6REDURjdb2c67uR3R | |||
system.server.2.pubkey= | |||
system.server.2.network.host=127.0.0.1 | |||
system.server.2.network.port=16020 | |||
system.server.2.network.secure=false | |||
@@ -55,7 +55,7 @@ system.server.2.network.secure=false | |||
###### #Consensus Participant3 ###### | |||
############################################ | |||
system.server.3.pubkey=endPsK36nse1dck4uF19zPvAMijCV336Y3zWdgb4rQG8QoRj5ktR | |||
system.server.3.pubkey= | |||
system.server.3.network.host=127.0.0.1 | |||
system.server.3.network.port=16030 | |||
system.server.3.network.secure=false | |||
@@ -1,19 +1,20 @@ | |||
#账本的种子;一段16进制字符,最长可以包含64个字符;可以用字符“-”分隔,以便更容易读取; | |||
#不同的账本,种子不能相同 | |||
ledger.seed=932dfe23-fe23232f-283f32fa-dd32aa76-8322ca2f-56236cda-7136b322-cb323ffe | |||
#账本的描述名称;此属性不参与共识,仅仅在当前参与方的本地节点用于描述用途; | |||
#ledger.name= | |||
#参与方的个数,后续以 cons_parti.id 分别标识每一个参与方的配置; | |||
#参与方的个数,后续以cons_parti.id分别标识每一个参与方的配置; | |||
cons_parti.count=4 | |||
#第0个参与方的名称 | |||
cons_parti.0.name=xx-0.com | |||
#第0个参与方的名称(不同参与方名称不能相同) | |||
cons_parti.0.name= | |||
#第0个参与方的公钥文件路径 | |||
cons_parti.0.pubkey-path= | |||
#第0个参与方的公钥内容(由keygen工具生成),此参数优先于 pubkey-path 参数 | |||
cons_parti.0.pubkey=endPsK36koyFr1D245Sa9j83vt6pZUdFBJoJRB3xAsWM6cwhRbna | |||
cons_parti.0.pubkey= | |||
#第0个参与方的账本初始服务的主机 | |||
cons_parti.0.initializer.host=127.0.0.1 | |||
#第0个参与方的账本初始服务的端口 | |||
@@ -23,11 +24,11 @@ cons_parti.0.initializer.secure=false | |||
#第1个参与方的名称 | |||
cons_parti.1.name=xx-1.com | |||
cons_parti.1.name= | |||
#第1个参与方的公钥文件路径 | |||
cons_parti.1.pubkey-path= | |||
#第1个参与方的公钥内容(由keygen工具生成),此参数优先于 pubkey-path 参数 | |||
cons_parti.1.pubkey=endPsK36sC5JdPCDPDAXUwZtS3sxEmqEhFcC4whayAsTTh8Z6eoZ | |||
cons_parti.1.pubkey= | |||
#第1个参与方的账本初始服务的主机 | |||
cons_parti.1.initializer.host=127.0.0.1 | |||
#第1个参与方的账本初始服务的端口 | |||
@@ -37,11 +38,11 @@ cons_parti.1.initializer.secure=false | |||
#第2个参与方的名称 | |||
cons_parti.2.name=xx-2.com | |||
cons_parti.2.name= | |||
#第2个参与方的公钥文件路径 | |||
cons_parti.2.pubkey-path= | |||
#第2个参与方的公钥内容(由keygen工具生成),此参数优先于 pubkey-path 参数 | |||
cons_parti.2.pubkey=endPsK36jEG281HMHeh6oSqzqLkT95DTnCM6REDURjdb2c67uR3R | |||
cons_parti.2.pubkey= | |||
#第2个参与方的账本初始服务的主机 | |||
cons_parti.2.initializer.host=127.0.0.1 | |||
#第2个参与方的账本初始服务的端口 | |||
@@ -51,11 +52,11 @@ cons_parti.2.initializer.secure=false | |||
#第3个参与方的名称 | |||
cons_parti.3.name=xx-3.com | |||
cons_parti.3.name= | |||
#第3个参与方的公钥文件路径 | |||
cons_parti.3.pubkey-path= | |||
#第3个参与方的公钥内容(由keygen工具生成),此参数优先于 pubkey-path 参数 | |||
cons_parti.3.pubkey=endPsK36nse1dck4uF19zPvAMijCV336Y3zWdgb4rQG8QoRj5ktR | |||
cons_parti.3.pubkey= | |||
#第3个参与方的账本初始服务的主机 | |||
cons_parti.3.initializer.host=127.0.0.1 | |||
#第3个参与方的账本初始服务的端口 | |||
@@ -2,22 +2,22 @@ | |||
local.parti.id=0 | |||
#当前参与方的公钥 | |||
local.parti.pubkey=endPsK36koyFr1D245Sa9j83vt6pZUdFBJoJRB3xAsWM6cwhRbna | |||
local.parti.pubkey= | |||
#当前参与方的私钥(密文编码) | |||
local.parti.privkey=177gjsj5PHeCpbAtJE7qnbmhuZMHAEKuMsd45zHkv8F8AWBvTBbff8yRKdCyT3kwrmAjSnY | |||
local.parti.privkey= | |||
#当前参与方的私钥解密密钥(原始口令的一次哈希,Base58格式),如果不设置,则启动过程中需要从控制台输入 | |||
local.parti.pwd=DYu3G8aGTMBW1WrTw76zxQJQU4DHLw9MLyy7peG4LKkY | |||
local.parti.pwd= | |||
#账本初始化完成后生成的"账本绑定配置文件"的输出目录 | |||
#推荐使用绝对路径,相对路径以当前文件(local.conf)所在目录为基准 | |||
ledger.binding.out=../.. | |||
ledger.binding.out=../ | |||
#账本数据库的连接字符 | |||
#rocksdb数据库连接格式:rocksdb://{path} | |||
#redis数据库连接格式:redis://{ip}:{prot}/{db} | |||
ledger.db.uri=rocksdb:///export/App08/peer/rocks.db/rocksdb0.db | |||
#rocksdb数据库连接格式:rocksdb://{path},例如:rocksdb:///export/App08/peer/rocks.db/rocksdb0.db | |||
#redis数据库连接格式:redis://{ip}:{prot}/{db},例如:redis://127.0.0.1:6379/0 | |||
ledger.db.uri= | |||
#账本数据库的连接口令 | |||
ledger.db.pwd= | |||
@@ -1,19 +0,0 @@ | |||
#绑定的账本的hash列表;以逗号分隔; | |||
ledger.bindings=6D2q2pRxWZEogGEESqKfceuBupRoukmmfVs8Fty1KuZ6i | |||
#第 1 个账本[6D2q2pRxWZEogGEESqKfceuBupRoukmmfVs8Fty1KuZ6i]的配置; | |||
#账本的当前共识参与方的ID; | |||
binding.6D2q2pRxWZEogGEESqKfceuBupRoukmmfVs8Fty1KuZ6i.parti.id=0 | |||
#账本的当前共识参与方的私钥文件的保存路径; | |||
binding.6D2q2pRxWZEogGEESqKfceuBupRoukmmfVs8Fty1KuZ6i.parti.pk-path= | |||
#账本的当前共识参与方的私钥内容(Base58编码);如果指定了,优先选用此属性,其次是 pk-path 属性; | |||
binding.6D2q2pRxWZEogGEESqKfceuBupRoukmmfVs8Fty1KuZ6i.parti.pk=177gjsj5PHeCpbAtJE7qnbmhuZMHAEKuMsd45zHkv8F8AWBvTBbff8yRKdCyT3kwrmAjSnY | |||
#账本的当前共识参与方的私钥文件的读取口令;可为空;如果为空时,节点的启动过程中需要手动从控制台输入; | |||
binding.6D2q2pRxWZEogGEESqKfceuBupRoukmmfVs8Fty1KuZ6i.parti.pwd=DYu3G8aGTMBW1WrTw76zxQJQU4DHLw9MLyy7peG4LKkY | |||
#账本的当前共识参与方地址 | |||
binding.6D2q2pRxWZEogGEESqKfceuBupRoukmmfVs8Fty1KuZ6i.parti.address=5SmFzgFtHtpbJwMCsmWTwjNGTk6SeMKU1522 | |||
#账本的存储数据库的连接字符串; | |||
binding.6D2q2pRxWZEogGEESqKfceuBupRoukmmfVs8Fty1KuZ6i.db.uri=rocksdb:///export/Data/rocksdb/rocksdb0.db | |||
#账本的存储数据库的连接口令; | |||
binding.6D2q2pRxWZEogGEESqKfceuBupRoukmmfVs8Fty1KuZ6i.db.pwd= |
@@ -5,5 +5,5 @@ PEER=$(ls $HOME/system | grep deployment-peer-) | |||
if [ ! -n "$PEER" ]; then | |||
echo "Peer Is Null !!!" | |||
else | |||
nohup java -jar -server -Xmx2g -Xms2g $HOME/system/$PEER -home=$HOME -c $HOME/config/init/mq/ledger-binding.conf -p 7080 $* & | |||
nohup java -jar -server -Xmx2g -Xms2g $HOME/system/$PEER -home=$HOME -c $HOME/config/ledger-binding.conf -p 7080 $* & | |||
fi |