Compare commits
12 Commits
ec367b9bbd
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
450c6df357 | ||
|
|
c9a6afdb38 | ||
|
|
22f93d0a7b | ||
|
|
8e3ae5639f | ||
|
|
c77f28fe30 | ||
| af48ee6f10 | |||
| 62acb1c453 | |||
|
|
decdcab1e5 | ||
|
|
ced82b18d7 | ||
|
|
acabbfa787 | ||
|
|
40197b2905 | ||
|
|
43b9bd6898 |
6
.gitignore
vendored
6
.gitignore
vendored
@@ -13,9 +13,13 @@
|
|||||||
?*.gitignore.*
|
?*.gitignore.*
|
||||||
?*.gitignore.*/
|
?*.gitignore.*/
|
||||||
*.gitomit
|
*.gitomit
|
||||||
*.gitomit/
|
|
||||||
*.gitomit.*
|
*.gitomit.*
|
||||||
|
*.gitomit/
|
||||||
*.gitomit.*/
|
*.gitomit.*/
|
||||||
|
*.nogit
|
||||||
|
*.nogit.*
|
||||||
|
*.nogit/
|
||||||
|
*.nogit.*/
|
||||||
# 保留
|
# 保留
|
||||||
!.gitignore
|
!.gitignore
|
||||||
!.gitignore.*
|
!.gitignore.*
|
||||||
|
|||||||
@@ -1,234 +0,0 @@
|
|||||||
<mxfile host="65bd71144e">
|
|
||||||
<diagram id="tEJiczfqJVlhZvufAVre" name="Page-1">
|
|
||||||
<mxGraphModel dx="845" dy="542" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
|
|
||||||
<root>
|
|
||||||
<mxCell id="0"/>
|
|
||||||
<mxCell id="1" parent="0"/>
|
|
||||||
<mxCell id="2" value="Data" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#008a00;strokeColor=#005700;fontColor=#ffffff;" parent="1" vertex="1">
|
|
||||||
<mxGeometry x="40" y="90" width="120" height="60" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="6" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=classic;startFill=1;" parent="1" source="4" target="5" edge="1">
|
|
||||||
<mxGeometry relative="1" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="4" value="Entropy<br>16 Bytes" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#008a00;strokeColor=#005700;fontColor=#ffffff;" parent="1" vertex="1">
|
|
||||||
<mxGeometry x="10" y="250" width="120" height="60" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="9" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="5" target="8" edge="1">
|
|
||||||
<mxGeometry relative="1" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="5" value="bip39" style="shape=parallelogram;perimeter=parallelogramPerimeter;whiteSpace=wrap;html=1;fixedSize=1;rounded=1;fontColor=#ffffff;strokeColor=#A50040;fillColor=#d80073;" parent="1" vertex="1">
|
|
||||||
<mxGeometry x="160" y="250" width="120" height="60" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="7" value="Algorithm" style="shape=parallelogram;perimeter=parallelogramPerimeter;whiteSpace=wrap;html=1;fixedSize=1;rounded=1;fontColor=#ffffff;strokeColor=#A50040;fillColor=#d80073;" parent="1" vertex="1">
|
|
||||||
<mxGeometry x="230" y="90" width="120" height="60" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="11" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="8" target="10" edge="1">
|
|
||||||
<mxGeometry relative="1" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="12" value="" style="edgeStyle=elbowEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=classic;startFill=1;" parent="1" source="8" target="5" edge="1">
|
|
||||||
<mxGeometry relative="1" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="8" value="Mnemonic ^ 密语 ^ Secword<br>12 words" style="whiteSpace=wrap;html=1;rounded=1;fontColor=#ffffff;strokeColor=#005700;fillColor=#008a00;" parent="1" vertex="1">
|
|
||||||
<mxGeometry x="310" y="250" width="120" height="60" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="13" style="edgeStyle=elbowEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=classic;startFill=1;" parent="1" source="10" target="8" edge="1">
|
|
||||||
<mxGeometry relative="1" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="15" value="" style="edgeStyle=elbowEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=none;startFill=0;" parent="1" source="10" target="14" edge="1">
|
|
||||||
<mxGeometry relative="1" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="10" value="hdkey" style="shape=parallelogram;perimeter=parallelogramPerimeter;whiteSpace=wrap;html=1;fixedSize=1;rounded=1;fontColor=#ffffff;strokeColor=#A50040;fillColor=#d80073;" parent="1" vertex="1">
|
|
||||||
<mxGeometry x="470" y="250" width="120" height="60" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="17" value="" style="edgeStyle=elbowEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=none;startFill=0;" parent="1" source="14" target="16" edge="1">
|
|
||||||
<mxGeometry relative="1" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="48" value="" style="edgeStyle=elbowEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=none;startFill=0;" parent="1" source="14" target="47" edge="1">
|
|
||||||
<mxGeometry relative="1" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="59" style="edgeStyle=elbowEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=none;startFill=0;" parent="1" source="14" target="58" edge="1">
|
|
||||||
<mxGeometry relative="1" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="19" value="" style="edgeStyle=elbowEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=none;startFill=0;" parent="1" source="16" target="18" edge="1">
|
|
||||||
<mxGeometry relative="1" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="16" value="椭圆曲线算法<br>secp256k1" style="shape=parallelogram;perimeter=parallelogramPerimeter;whiteSpace=wrap;html=1;fixedSize=1;rounded=1;fontColor=#ffffff;strokeColor=#A50040;fillColor=#d80073;" parent="1" vertex="1">
|
|
||||||
<mxGeometry x="770" y="250" width="120" height="60" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="96" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="18" target="53" edge="1">
|
|
||||||
<mxGeometry relative="1" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="98" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" parent="1" source="18" target="57" edge="1">
|
|
||||||
<mxGeometry relative="1" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="18" value="public key ^ 公钥<br>264 bits = 33 Bytes = 66 Hex" style="rounded=1;whiteSpace=wrap;html=1;fontColor=#ffffff;strokeColor=#005700;fillColor=#008a00;" parent="1" vertex="1">
|
|
||||||
<mxGeometry x="910" y="250" width="120" height="60" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="28" value="" style="edgeStyle=elbowEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=none;startFill=0;" parent="1" source="20" target="27" edge="1">
|
|
||||||
<mxGeometry relative="1" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="20" value="<ol><li>sha256</li><li>ripemd160</li></ol>" style="shape=parallelogram;perimeter=parallelogramPerimeter;whiteSpace=wrap;html=1;fixedSize=1;rounded=1;fontColor=#ffffff;strokeColor=#A50040;fillColor=#d80073;align=left;" parent="1" vertex="1">
|
|
||||||
<mxGeometry x="1055" y="130" width="120" height="60" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="30" value="" style="edgeStyle=elbowEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=none;startFill=0;" parent="1" source="24" target="29" edge="1">
|
|
||||||
<mxGeometry relative="1" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="24" value="<ol><li>decompress</li><li>keccak256</li><li>slice(40)</li></ol>" style="shape=parallelogram;perimeter=parallelogramPerimeter;whiteSpace=wrap;html=1;fixedSize=1;rounded=1;fontColor=#ffffff;strokeColor=#A50040;fillColor=#d80073;align=left;" parent="1" vertex="1">
|
|
||||||
<mxGeometry x="1055" y="250" width="120" height="60" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="32" value="" style="edgeStyle=elbowEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=none;startFill=0;" parent="1" source="25" target="31" edge="1">
|
|
||||||
<mxGeometry relative="1" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="25" value="<ol><li>sha256</li><li>ripemd160</li></ol>" style="shape=parallelogram;perimeter=parallelogramPerimeter;whiteSpace=wrap;html=1;fixedSize=1;rounded=1;fontColor=#ffffff;strokeColor=#A50040;fillColor=#d80073;align=left;" parent="1" vertex="1">
|
|
||||||
<mxGeometry x="1050" y="360" width="120" height="60" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="34" value="" style="edgeStyle=elbowEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=classic;startFill=1;" parent="1" source="27" target="33" edge="1">
|
|
||||||
<mxGeometry relative="1" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="27" value="position of BTC<br>20 Bytes = 40 Hex" style="whiteSpace=wrap;html=1;rounded=1;fontColor=#ffffff;align=center;strokeColor=#005700;fillColor=#008a00;" parent="1" vertex="1">
|
|
||||||
<mxGeometry x="1190" y="130" width="120" height="60" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="36" style="edgeStyle=elbowEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=none;startFill=0;" parent="1" source="29" target="35" edge="1">
|
|
||||||
<mxGeometry relative="1" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="29" value="position of ETH<br>20 Bytes = 40 Hex" style="rounded=1;whiteSpace=wrap;html=1;fontColor=#ffffff;align=center;strokeColor=#005700;fillColor=#008a00;" parent="1" vertex="1">
|
|
||||||
<mxGeometry x="1190" y="250" width="120" height="60" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="38" value="" style="edgeStyle=elbowEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=none;startFill=0;" parent="1" source="31" target="37" edge="1">
|
|
||||||
<mxGeometry relative="1" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="31" value="Position of TIC<br>20 Bytes = 40 Hex" style="rounded=1;whiteSpace=wrap;html=1;fontColor=#ffffff;align=center;strokeColor=#005700;fillColor=#008a00;" parent="1" vertex="1">
|
|
||||||
<mxGeometry x="1190" y="360" width="120" height="60" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="42" value="" style="edgeStyle=elbowEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=classic;startFill=1;" parent="1" source="33" target="41" edge="1">
|
|
||||||
<mxGeometry relative="1" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="33" value="<ol><li>protocol prefix +1B</li><li>cksum postfix +4B</li><li>base58btc</li></ol>" style="shape=parallelogram;perimeter=parallelogramPerimeter;whiteSpace=wrap;html=1;fixedSize=1;rounded=1;fontColor=#ffffff;strokeColor=#A50040;fillColor=#d80073;align=left;" parent="1" vertex="1">
|
|
||||||
<mxGeometry x="1340" y="130" width="150" height="60" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="39" style="edgeStyle=elbowEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=classic;startFill=1;" parent="1" source="35" target="29" edge="1">
|
|
||||||
<mxGeometry relative="1" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="91" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="35" target="43" edge="1">
|
|
||||||
<mxGeometry relative="1" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="35" value="<ol><li><span>大小写(EIP55)</span><br></li><li><span>'0x' prefix</span></li></ol>" style="shape=parallelogram;perimeter=parallelogramPerimeter;whiteSpace=wrap;html=1;fixedSize=1;rounded=1;fontColor=#ffffff;strokeColor=#A50040;fillColor=#d80073;align=left;" parent="1" vertex="1">
|
|
||||||
<mxGeometry x="1340" y="250" width="150" height="60" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="40" style="edgeStyle=elbowEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=classic;startFill=1;" parent="1" source="37" target="31" edge="1">
|
|
||||||
<mxGeometry relative="1" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="46" value="" style="edgeStyle=elbowEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=classic;startFill=1;" parent="1" source="37" target="45" edge="1">
|
|
||||||
<mxGeometry relative="1" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="37" value="<ol><li>world prefix +1B</li><li>cksum postfix +3B</li><li>base64url</li></ol>" style="shape=parallelogram;perimeter=parallelogramPerimeter;whiteSpace=wrap;html=1;fixedSize=1;rounded=1;fontColor=#ffffff;strokeColor=#A50040;fillColor=#d80073;align=left;" parent="1" vertex="1">
|
|
||||||
<mxGeometry x="1340" y="360" width="150" height="60" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="41" value="address of BTC<br>26~34 b58" style="rounded=1;whiteSpace=wrap;html=1;fontColor=#ffffff;align=center;strokeColor=#005700;fillColor=#008a00;" parent="1" vertex="1">
|
|
||||||
<mxGeometry x="1520" y="130" width="120" height="60" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="92" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="43" target="35" edge="1">
|
|
||||||
<mxGeometry relative="1" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="43" value="address of ETH<br>'0x' + 40 Hex" style="rounded=1;whiteSpace=wrap;html=1;fontColor=#ffffff;align=center;strokeColor=#005700;fillColor=#008a00;" parent="1" vertex="1">
|
|
||||||
<mxGeometry x="1520" y="250" width="120" height="60" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="45" value="address of TIC<br>32 b64u" style="rounded=1;whiteSpace=wrap;html=1;fontColor=#ffffff;align=center;strokeColor=#005700;fillColor=#008a00;" parent="1" vertex="1">
|
|
||||||
<mxGeometry x="1520" y="360" width="120" height="60" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="50" value="" style="edgeStyle=elbowEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=none;startFill=0;" parent="1" source="47" target="49" edge="1">
|
|
||||||
<mxGeometry relative="1" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="47" value="sign ^ 签署" style="shape=parallelogram;perimeter=parallelogramPerimeter;whiteSpace=wrap;html=1;fixedSize=1;rounded=1;fontColor=#ffffff;strokeColor=#A50040;fillColor=#d80073;" parent="1" vertex="1">
|
|
||||||
<mxGeometry x="620" y="430" width="120" height="60" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="56" style="edgeStyle=elbowEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;startArrow=none;startFill=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" parent="1" source="51" target="53" edge="1">
|
|
||||||
<mxGeometry relative="1" as="geometry">
|
|
||||||
<Array as="points"/>
|
|
||||||
</mxGeometry>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="97" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" parent="1" source="49" target="53" edge="1">
|
|
||||||
<mxGeometry relative="1" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="49" value="Signature ^ 签印<br>71~72 Bytes = 142/144 Hex" style="rounded=1;whiteSpace=wrap;html=1;fontColor=#ffffff;strokeColor=#005700;fillColor=#008a00;" parent="1" vertex="1">
|
|
||||||
<mxGeometry x="620" y="560" width="120" height="60" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="53" value="verify ^ 验签" style="shape=parallelogram;perimeter=parallelogramPerimeter;whiteSpace=wrap;html=1;fixedSize=1;rounded=1;fontColor=#ffffff;strokeColor=#A50040;fillColor=#d80073;" parent="1" vertex="1">
|
|
||||||
<mxGeometry x="910" y="430" width="120" height="60" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="103" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=1;entryY=0.5;entryDx=0;entryDy=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;" parent="1" source="57" target="64" edge="1">
|
|
||||||
<mxGeometry relative="1" as="geometry">
|
|
||||||
<Array as="points">
|
|
||||||
<mxPoint x="1000" y="40"/>
|
|
||||||
</Array>
|
|
||||||
</mxGeometry>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="57" value="encrypt ^ 加密" style="shape=parallelogram;perimeter=parallelogramPerimeter;whiteSpace=wrap;html=1;fixedSize=1;rounded=1;fontColor=#ffffff;strokeColor=#A50040;fillColor=#d80073;" parent="1" vertex="1">
|
|
||||||
<mxGeometry x="910" y="120" width="120" height="60" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="105" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" target="61" edge="1">
|
|
||||||
<mxGeometry relative="1" as="geometry">
|
|
||||||
<mxPoint x="710" y="150" as="sourcePoint"/>
|
|
||||||
</mxGeometry>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="58" value="decrypt ^ 解密" style="shape=parallelogram;perimeter=parallelogramPerimeter;whiteSpace=wrap;html=1;fixedSize=1;rounded=1;fontColor=#ffffff;strokeColor=#A50040;fillColor=#d80073;" parent="1" vertex="1">
|
|
||||||
<mxGeometry x="620" y="120" width="120" height="60" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="104" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" parent="1" source="64" target="58" edge="1">
|
|
||||||
<mxGeometry relative="1" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="64" value="ciphertext ^ 密文" style="whiteSpace=wrap;html=1;rounded=1;fontColor=#ffffff;strokeColor=#005700;fillColor=#008a00;" parent="1" vertex="1">
|
|
||||||
<mxGeometry x="770" y="10" width="120" height="60" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="87" value="" style="endArrow=classic;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" parent="1" source="18" target="25" edge="1">
|
|
||||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
|
||||||
<mxPoint x="8" y="610" as="sourcePoint"/>
|
|
||||||
<mxPoint x="208" y="650" as="targetPoint"/>
|
|
||||||
</mxGeometry>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="88" value="" style="endArrow=classic;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="18" target="20" edge="1">
|
|
||||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
|
||||||
<mxPoint x="80" y="830" as="sourcePoint"/>
|
|
||||||
<mxPoint x="130" y="780" as="targetPoint"/>
|
|
||||||
</mxGeometry>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="89" value="" style="endArrow=classic;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" parent="1" source="18" target="24" edge="1">
|
|
||||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
|
||||||
<mxPoint x="2" y="610" as="sourcePoint"/>
|
|
||||||
<mxPoint x="328" y="740" as="targetPoint"/>
|
|
||||||
</mxGeometry>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="14" value="private key ^ 私钥<br>256 bits = 32 Bytes = 64 Hex" style="whiteSpace=wrap;html=1;rounded=1;fontColor=#ffffff;strokeColor=#005700;fillColor=#008a00;" parent="1" vertex="1">
|
|
||||||
<mxGeometry x="620" y="250" width="120" height="60" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="95" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="51" target="47" edge="1">
|
|
||||||
<mxGeometry relative="1" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="51" value="作品=&gt;哈希" style="whiteSpace=wrap;html=1;rounded=1;fontColor=#ffffff;strokeColor=#005700;fillColor=#008a00;" parent="1" vertex="1">
|
|
||||||
<mxGeometry x="770" y="430" width="120" height="60" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="106" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="61" target="57" edge="1">
|
|
||||||
<mxGeometry relative="1" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="61" value="plaintext ^ 明文" style="whiteSpace=wrap;html=1;rounded=1;fontColor=#ffffff;strokeColor=#005700;fillColor=#008a00;" parent="1" vertex="1">
|
|
||||||
<mxGeometry x="770" y="120" width="120" height="60" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="111" value="prikey_to_pubkey" style="shape=partialRectangle;whiteSpace=wrap;html=1;bottom=1;right=1;left=1;top=0;fillColor=#1ba1e2;routingCenterX=-0.5;strokeColor=#006EAF;fontColor=#ffffff;" parent="1" vertex="1">
|
|
||||||
<mxGeometry x="680" y="650" width="290" height="30" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="112" value="secword_to_keypair" style="shape=partialRectangle;whiteSpace=wrap;html=1;bottom=1;right=1;left=1;top=0;fillColor=#1ba1e2;routingCenterX=-0.5;strokeColor=#006EAF;fontColor=#ffffff;" parent="1" vertex="1">
|
|
||||||
<mxGeometry x="420" y="710" width="610" height="30" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="113" value="pubkey_to_address" style="shape=partialRectangle;whiteSpace=wrap;html=1;bottom=1;right=1;left=1;top=0;fillColor=#1ba1e2;routingCenterX=-0.5;strokeColor=#006EAF;fontColor=#ffffff;" parent="1" vertex="1">
|
|
||||||
<mxGeometry x="970" y="650" width="630" height="30" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="114" value="prikey_to_address" style="shape=partialRectangle;whiteSpace=wrap;html=1;bottom=1;right=1;left=1;top=0;fillColor=#1ba1e2;routingCenterX=-0.5;strokeColor=#006EAF;fontColor=#ffffff;" parent="1" vertex="1">
|
|
||||||
<mxGeometry x="680" y="730" width="920" height="30" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="115" value="secword_to_address, secword_to_account" style="shape=partialRectangle;whiteSpace=wrap;html=1;bottom=1;right=1;left=1;top=0;fillColor=#1ba1e2;routingCenterX=-0.5;strokeColor=#006EAF;fontColor=#ffffff;" parent="1" vertex="1">
|
|
||||||
<mxGeometry x="360" y="770" width="1240" height="30" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
</root>
|
|
||||||
</mxGraphModel>
|
|
||||||
</diagram>
|
|
||||||
</mxfile>
|
|
||||||
@@ -24,7 +24,7 @@
|
|||||||
在前后端软件的 package.json 的依赖清单中引入本库:
|
在前后端软件的 package.json 的依赖清单中引入本库:
|
||||||
|
|
||||||
```
|
```
|
||||||
npm install git+https://git.faronear.org/npm/tic-crypto#RELEASE_OR_BRANCH --save
|
npm install git+https://git.tic.cc/open/tic-crypto#RELEASE_OR_BRANCH --save
|
||||||
```
|
```
|
||||||
|
|
||||||
## 用法
|
## 用法
|
||||||
|
|||||||
@@ -1,230 +0,0 @@
|
|||||||
<mxfile host="65bd71144e">
|
|
||||||
<diagram id="tEJiczfqJVlhZvufAVre" name="Page-1">
|
|
||||||
<mxGraphModel dx="845" dy="542" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
|
|
||||||
<root>
|
|
||||||
<mxCell id="0"/>
|
|
||||||
<mxCell id="1" parent="0"/>
|
|
||||||
<mxCell id="2" value="Data" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#008a00;strokeColor=#005700;fontColor=#ffffff;" parent="1" vertex="1">
|
|
||||||
<mxGeometry x="40" y="40" width="120" height="60" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="6" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=classic;startFill=1;" parent="1" source="4" target="5" edge="1">
|
|
||||||
<mxGeometry relative="1" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="4" value="Entropy<br>16 Bytes" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#008a00;strokeColor=#005700;fontColor=#ffffff;" parent="1" vertex="1">
|
|
||||||
<mxGeometry x="308" y="20" width="120" height="60" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="9" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="5" target="8" edge="1">
|
|
||||||
<mxGeometry relative="1" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="5" value="bip39" style="shape=parallelogram;perimeter=parallelogramPerimeter;whiteSpace=wrap;html=1;fixedSize=1;rounded=1;fontColor=#ffffff;strokeColor=#A50040;fillColor=#d80073;" parent="1" vertex="1">
|
|
||||||
<mxGeometry x="308" y="120" width="120" height="60" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="7" value="Algorithm" style="shape=parallelogram;perimeter=parallelogramPerimeter;whiteSpace=wrap;html=1;fixedSize=1;rounded=1;fontColor=#ffffff;strokeColor=#A50040;fillColor=#d80073;" parent="1" vertex="1">
|
|
||||||
<mxGeometry x="40" y="130" width="120" height="60" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="11" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="8" target="10" edge="1">
|
|
||||||
<mxGeometry relative="1" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="12" value="" style="edgeStyle=elbowEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=classic;startFill=1;" parent="1" source="8" target="5" edge="1">
|
|
||||||
<mxGeometry relative="1" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="8" value="Mnemonic ^ 密语 ^ Secword<br>12 words" style="whiteSpace=wrap;html=1;rounded=1;fontColor=#ffffff;strokeColor=#005700;fillColor=#008a00;" parent="1" vertex="1">
|
|
||||||
<mxGeometry x="308" y="220" width="120" height="60" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="13" style="edgeStyle=elbowEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=classic;startFill=1;" parent="1" source="10" target="8" edge="1">
|
|
||||||
<mxGeometry relative="1" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="15" value="" style="edgeStyle=elbowEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=none;startFill=0;" parent="1" source="10" target="14" edge="1">
|
|
||||||
<mxGeometry relative="1" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="10" value="hdkey" style="shape=parallelogram;perimeter=parallelogramPerimeter;whiteSpace=wrap;html=1;fixedSize=1;rounded=1;fontColor=#ffffff;strokeColor=#A50040;fillColor=#d80073;" parent="1" vertex="1">
|
|
||||||
<mxGeometry x="308" y="324.5" width="120" height="60" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="17" value="" style="edgeStyle=elbowEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=none;startFill=0;" parent="1" source="14" target="16" edge="1">
|
|
||||||
<mxGeometry relative="1" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="48" value="" style="edgeStyle=elbowEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=none;startFill=0;" parent="1" source="14" target="47" edge="1">
|
|
||||||
<mxGeometry relative="1" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="59" style="edgeStyle=elbowEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=none;startFill=0;" parent="1" source="14" target="58" edge="1">
|
|
||||||
<mxGeometry relative="1" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="14" value="private key ^ 私钥<br>256 bits = 32 Bytes = 64 Hex" style="whiteSpace=wrap;html=1;rounded=1;fontColor=#ffffff;strokeColor=#005700;fillColor=#008a00;" parent="1" vertex="1">
|
|
||||||
<mxGeometry x="308" y="420" width="120" height="60" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="19" value="" style="edgeStyle=elbowEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=none;startFill=0;" parent="1" source="16" target="18" edge="1">
|
|
||||||
<mxGeometry relative="1" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="16" value="椭圆曲线算法<br>secp256k1" style="shape=parallelogram;perimeter=parallelogramPerimeter;whiteSpace=wrap;html=1;fixedSize=1;rounded=1;fontColor=#ffffff;strokeColor=#A50040;fillColor=#d80073;" parent="1" vertex="1">
|
|
||||||
<mxGeometry x="308" y="520" width="120" height="60" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="54" value="" style="edgeStyle=elbowEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=none;startFill=0;" parent="1" source="18" target="53" edge="1">
|
|
||||||
<mxGeometry relative="1" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="84" style="edgeStyle=elbowEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;startArrow=none;startFill=0;" parent="1" source="18" target="57" edge="1">
|
|
||||||
<mxGeometry relative="1" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="18" value="public key ^ 公钥<br>264 bits = 33 Bytes = 66 Hex" style="rounded=1;whiteSpace=wrap;html=1;fontColor=#ffffff;strokeColor=#005700;fillColor=#008a00;" parent="1" vertex="1">
|
|
||||||
<mxGeometry x="308" y="640" width="120" height="60" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="28" value="" style="edgeStyle=elbowEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=none;startFill=0;" parent="1" source="20" target="27" edge="1">
|
|
||||||
<mxGeometry relative="1" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="20" value="<ol><li>sha256</li><li>ripemd160</li></ol>" style="shape=parallelogram;perimeter=parallelogramPerimeter;whiteSpace=wrap;html=1;fixedSize=1;rounded=1;fontColor=#ffffff;strokeColor=#A50040;fillColor=#d80073;align=left;" parent="1" vertex="1">
|
|
||||||
<mxGeometry x="170" y="780" width="120" height="60" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="30" value="" style="edgeStyle=elbowEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=none;startFill=0;" parent="1" source="24" target="29" edge="1">
|
|
||||||
<mxGeometry relative="1" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="24" value="<ol><li>decompress</li><li>keccak256</li><li>slice(40)</li></ol>" style="shape=parallelogram;perimeter=parallelogramPerimeter;whiteSpace=wrap;html=1;fixedSize=1;rounded=1;fontColor=#ffffff;strokeColor=#A50040;fillColor=#d80073;align=left;" parent="1" vertex="1">
|
|
||||||
<mxGeometry x="312" y="780" width="120" height="60" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="32" value="" style="edgeStyle=elbowEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=none;startFill=0;" parent="1" source="25" target="31" edge="1">
|
|
||||||
<mxGeometry relative="1" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="25" value="<ol><li>sha256</li><li>ripemd160</li></ol>" style="shape=parallelogram;perimeter=parallelogramPerimeter;whiteSpace=wrap;html=1;fixedSize=1;rounded=1;fontColor=#ffffff;strokeColor=#A50040;fillColor=#d80073;align=left;" parent="1" vertex="1">
|
|
||||||
<mxGeometry x="469" y="780" width="120" height="60" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="34" value="" style="edgeStyle=elbowEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=classic;startFill=1;" parent="1" source="27" target="33" edge="1">
|
|
||||||
<mxGeometry relative="1" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="27" value="position of BTC<br>20 Bytes = 40 Hex" style="whiteSpace=wrap;html=1;rounded=1;fontColor=#ffffff;align=center;strokeColor=#005700;fillColor=#008a00;" parent="1" vertex="1">
|
|
||||||
<mxGeometry x="170" y="880" width="120" height="60" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="36" style="edgeStyle=elbowEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=none;startFill=0;" parent="1" source="29" target="35" edge="1">
|
|
||||||
<mxGeometry relative="1" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="29" value="position of ETH<br>20 Bytes = 40 Hex" style="rounded=1;whiteSpace=wrap;html=1;fontColor=#ffffff;align=center;strokeColor=#005700;fillColor=#008a00;" parent="1" vertex="1">
|
|
||||||
<mxGeometry x="318" y="879" width="120" height="60" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="38" value="" style="edgeStyle=elbowEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=none;startFill=0;" parent="1" source="31" target="37" edge="1">
|
|
||||||
<mxGeometry relative="1" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="31" value="Position of TIC<br>20 Bytes = 40 Hex" style="rounded=1;whiteSpace=wrap;html=1;fontColor=#ffffff;align=center;strokeColor=#005700;fillColor=#008a00;" parent="1" vertex="1">
|
|
||||||
<mxGeometry x="478" y="880" width="120" height="60" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="42" value="" style="edgeStyle=elbowEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=classic;startFill=1;" parent="1" source="33" target="41" edge="1">
|
|
||||||
<mxGeometry relative="1" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="33" value="<ol><li>protocol prefix +1B</li><li>cksum postfix +4B</li><li>base58btc</li></ol>" style="shape=parallelogram;perimeter=parallelogramPerimeter;whiteSpace=wrap;html=1;fixedSize=1;rounded=1;fontColor=#ffffff;strokeColor=#A50040;fillColor=#d80073;align=left;" parent="1" vertex="1">
|
|
||||||
<mxGeometry x="160" y="980" width="150" height="60" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="39" style="edgeStyle=elbowEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=classic;startFill=1;" parent="1" source="35" target="29" edge="1">
|
|
||||||
<mxGeometry relative="1" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="44" value="" style="edgeStyle=elbowEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=classic;startFill=1;" parent="1" source="35" target="43" edge="1">
|
|
||||||
<mxGeometry relative="1" as="geometry">
|
|
||||||
<Array as="points">
|
|
||||||
<mxPoint x="378" y="1060"/>
|
|
||||||
</Array>
|
|
||||||
</mxGeometry>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="35" value="<ol><li><span>大小写(EIP55)</span><br></li><li><span>'0x' prefix</span></li></ol>" style="shape=parallelogram;perimeter=parallelogramPerimeter;whiteSpace=wrap;html=1;fixedSize=1;rounded=1;fontColor=#ffffff;strokeColor=#A50040;fillColor=#d80073;align=left;" parent="1" vertex="1">
|
|
||||||
<mxGeometry x="312" y="980" width="150" height="60" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="40" style="edgeStyle=elbowEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=classic;startFill=1;" parent="1" source="37" target="31" edge="1">
|
|
||||||
<mxGeometry relative="1" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="46" value="" style="edgeStyle=elbowEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=classic;startFill=1;" parent="1" source="37" target="45" edge="1">
|
|
||||||
<mxGeometry relative="1" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="37" value="<ol><li>world prefix +1B</li><li>cksum postfix +3B</li><li>base64url</li></ol>" style="shape=parallelogram;perimeter=parallelogramPerimeter;whiteSpace=wrap;html=1;fixedSize=1;rounded=1;fontColor=#ffffff;strokeColor=#A50040;fillColor=#d80073;align=left;" parent="1" vertex="1">
|
|
||||||
<mxGeometry x="469" y="980" width="150" height="60" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="41" value="address of BTC<br>26~34 b58" style="rounded=1;whiteSpace=wrap;html=1;fontColor=#ffffff;align=center;strokeColor=#005700;fillColor=#008a00;" parent="1" vertex="1">
|
|
||||||
<mxGeometry x="170" y="1080" width="120" height="60" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="43" value="address of ETH<br>'0x' + 40 Hex" style="rounded=1;whiteSpace=wrap;html=1;fontColor=#ffffff;align=center;strokeColor=#005700;fillColor=#008a00;" parent="1" vertex="1">
|
|
||||||
<mxGeometry x="318" y="1080" width="120" height="60" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="45" value="address of TIC<br>32 b64u" style="rounded=1;whiteSpace=wrap;html=1;fontColor=#ffffff;align=center;strokeColor=#005700;fillColor=#008a00;" parent="1" vertex="1">
|
|
||||||
<mxGeometry x="479" y="1080" width="120" height="60" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="50" value="" style="edgeStyle=elbowEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=none;startFill=0;" parent="1" source="47" target="49" edge="1">
|
|
||||||
<mxGeometry relative="1" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="47" value="sign ^ 签署" style="shape=parallelogram;perimeter=parallelogramPerimeter;whiteSpace=wrap;html=1;fixedSize=1;rounded=1;fontColor=#ffffff;strokeColor=#A50040;fillColor=#d80073;" parent="1" vertex="1">
|
|
||||||
<mxGeometry x="140" y="420" width="120" height="60" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="56" style="edgeStyle=elbowEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;startArrow=none;startFill=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="49" target="53" edge="1">
|
|
||||||
<mxGeometry relative="1" as="geometry">
|
|
||||||
<Array as="points"/>
|
|
||||||
</mxGeometry>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="49" value="Signature ^ 签印<br>71~72 Bytes = 142/144 Hex" style="rounded=1;whiteSpace=wrap;html=1;fontColor=#ffffff;strokeColor=#005700;fillColor=#008a00;" parent="1" vertex="1">
|
|
||||||
<mxGeometry x="140" y="520" width="120" height="60" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="52" style="edgeStyle=elbowEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;startArrow=none;startFill=0;" parent="1" source="51" target="47" edge="1">
|
|
||||||
<mxGeometry relative="1" as="geometry">
|
|
||||||
<Array as="points">
|
|
||||||
<mxPoint x="70" y="520"/>
|
|
||||||
</Array>
|
|
||||||
</mxGeometry>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="55" style="edgeStyle=elbowEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=none;startFill=0;" parent="1" source="51" target="53" edge="1">
|
|
||||||
<mxGeometry relative="1" as="geometry">
|
|
||||||
<Array as="points">
|
|
||||||
<mxPoint x="70" y="620"/>
|
|
||||||
</Array>
|
|
||||||
</mxGeometry>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="51" value="作品=&gt;哈希" style="whiteSpace=wrap;html=1;rounded=1;fontColor=#ffffff;strokeColor=#005700;fillColor=#008a00;" parent="1" vertex="1">
|
|
||||||
<mxGeometry x="10" y="520" width="120" height="60" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="53" value="verify ^ 验签" style="shape=parallelogram;perimeter=parallelogramPerimeter;whiteSpace=wrap;html=1;fixedSize=1;rounded=1;fontColor=#ffffff;strokeColor=#A50040;fillColor=#d80073;" parent="1" vertex="1">
|
|
||||||
<mxGeometry x="140" y="640" width="120" height="60" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="82" style="edgeStyle=elbowEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=1;entryDx=0;entryDy=0;startArrow=none;startFill=0;" parent="1" source="57" target="64" edge="1">
|
|
||||||
<mxGeometry relative="1" as="geometry">
|
|
||||||
<Array as="points">
|
|
||||||
<mxPoint x="659" y="630"/>
|
|
||||||
</Array>
|
|
||||||
</mxGeometry>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="57" value="encrypt ^ 加密" style="shape=parallelogram;perimeter=parallelogramPerimeter;whiteSpace=wrap;html=1;fixedSize=1;rounded=1;fontColor=#ffffff;strokeColor=#A50040;fillColor=#d80073;" parent="1" vertex="1">
|
|
||||||
<mxGeometry x="469" y="640" width="120" height="60" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="80" style="edgeStyle=elbowEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;startArrow=none;startFill=0;" parent="1" source="58" target="61" edge="1">
|
|
||||||
<mxGeometry relative="1" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="58" value="decrypt ^ 解密" style="shape=parallelogram;perimeter=parallelogramPerimeter;whiteSpace=wrap;html=1;fixedSize=1;rounded=1;fontColor=#ffffff;strokeColor=#A50040;fillColor=#d80073;" parent="1" vertex="1">
|
|
||||||
<mxGeometry x="469" y="420" width="120" height="60" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="81" style="edgeStyle=elbowEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=none;startFill=0;" parent="1" source="61" target="57" edge="1">
|
|
||||||
<mxGeometry relative="1" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="61" value="plaintext ^ 明文" style="whiteSpace=wrap;html=1;rounded=1;fontColor=#ffffff;strokeColor=#005700;fillColor=#008a00;" parent="1" vertex="1">
|
|
||||||
<mxGeometry x="469" y="520" width="120" height="60" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="83" style="edgeStyle=elbowEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=1;entryY=0.5;entryDx=0;entryDy=0;startArrow=none;startFill=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;" parent="1" source="64" target="58" edge="1">
|
|
||||||
<mxGeometry relative="1" as="geometry">
|
|
||||||
<Array as="points">
|
|
||||||
<mxPoint x="659" y="490"/>
|
|
||||||
</Array>
|
|
||||||
</mxGeometry>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="64" value="ciphertext ^ 密文" style="whiteSpace=wrap;html=1;rounded=1;fontColor=#ffffff;strokeColor=#005700;fillColor=#008a00;" parent="1" vertex="1">
|
|
||||||
<mxGeometry x="599" y="520" width="120" height="60" as="geometry"/>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="87" value="" style="endArrow=classic;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="18" target="25" edge="1">
|
|
||||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
|
||||||
<mxPoint x="378" y="750" as="sourcePoint"/>
|
|
||||||
<mxPoint x="578" y="790" as="targetPoint"/>
|
|
||||||
</mxGeometry>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="88" value="" style="endArrow=classic;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" parent="1" source="18" target="20" edge="1">
|
|
||||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
|
||||||
<mxPoint x="450" y="970" as="sourcePoint"/>
|
|
||||||
<mxPoint x="500" y="920" as="targetPoint"/>
|
|
||||||
</mxGeometry>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="89" value="" style="endArrow=classic;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="18" target="24" edge="1">
|
|
||||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
|
||||||
<mxPoint x="372" y="750" as="sourcePoint"/>
|
|
||||||
<mxPoint x="698" y="880" as="targetPoint"/>
|
|
||||||
</mxGeometry>
|
|
||||||
</mxCell>
|
|
||||||
</root>
|
|
||||||
</mxGraphModel>
|
|
||||||
</diagram>
|
|
||||||
</mxfile>
|
|
||||||
BIN
README_cryptoflow.drawio.png
Normal file
BIN
README_cryptoflow.drawio.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 265 KiB |
@@ -6,17 +6,18 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"base32-decode": "^1.0.0",
|
"base32-decode": "^1.0.0",
|
||||||
"base32-encode": "^1.2.0",
|
"base32-encode": "^1.2.0",
|
||||||
"big-integer": "^1.6.51",
|
"big-integer": "^1.6.52",
|
||||||
"bip39": "^3.0.4",
|
"bip39": "^3.0.4",
|
||||||
"bs58check": "^2.1.2",
|
"bs58check": "^2.1.2",
|
||||||
"eccrypto-js": "^5.4.0",
|
"eccrypto-js": "^5.4.0",
|
||||||
"ethereum-rsa": "^1.0.5",
|
"ethereum-rsa": "^1.0.5",
|
||||||
"hdkey": "^2.0.1",
|
"hdkey": "^2.0.1",
|
||||||
|
"ipfs-only-hash": "^4.0.0",
|
||||||
"js-crypto-key-utils": "^1.0.4",
|
"js-crypto-key-utils": "^1.0.4",
|
||||||
"keccak": "^3.0.2",
|
"keccak": "^3.0.2",
|
||||||
"secp256k1": "^4.0.3",
|
"secp256k1": "^4.0.3",
|
||||||
"tweetnacl": "^1.0.3",
|
"tronweb": "^6.0.3",
|
||||||
"uuid": "^8.3.2"
|
"tweetnacl": "^1.0.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"docdash": "^1.2.0",
|
"docdash": "^1.2.0",
|
||||||
|
|||||||
@@ -17,6 +17,16 @@
|
|||||||
*.sfomit.*
|
*.sfomit.*
|
||||||
*.sfomit/
|
*.sfomit/
|
||||||
*.sfomit.*/
|
*.sfomit.*/
|
||||||
|
*.nosf
|
||||||
|
*.nosf.*
|
||||||
|
*.nosf/
|
||||||
|
*.nosf.*/
|
||||||
|
|
||||||
|
## everything 'git pull or fetch' will update `.git/FETCH_HEAD`, even if the content doesn't change. To avoid too many useless updates of this file in Seafile history:
|
||||||
|
FETCH_HEAD
|
||||||
|
*/FETCH_HEAD
|
||||||
|
|
||||||
|
.Trash/
|
||||||
|
|
||||||
.DS_Store
|
.DS_Store
|
||||||
*/.DS_Store
|
*/.DS_Store
|
||||||
@@ -44,12 +54,18 @@ _desktop.ini
|
|||||||
node_modules/
|
node_modules/
|
||||||
*/node_modules/
|
*/node_modules/
|
||||||
package-lock.json
|
package-lock.json
|
||||||
|
*/package-lock.json
|
||||||
|
|
||||||
pages4loader.json5
|
pages4loader.json5
|
||||||
|
*/pages4loader.json5
|
||||||
|
|
||||||
.deploy_git/
|
.deploy_git/
|
||||||
*/.deploy_git/
|
*/.deploy_git/
|
||||||
|
|
||||||
|
# next.js 项目
|
||||||
|
.next/
|
||||||
|
*/.next/
|
||||||
|
|
||||||
# HBuilder 目录
|
# HBuilder 目录
|
||||||
unpackage/
|
unpackage/
|
||||||
*/unpackage/
|
*/unpackage/
|
||||||
|
|||||||
32
test.js
32
test.js
@@ -16,11 +16,7 @@ function ECPointDecompress (comp) {
|
|||||||
var x = new bigInt(comp.substring(2), 16)
|
var x = new bigInt(comp.substring(2), 16)
|
||||||
// y mod p = +-(x^3 + 7)^((p+1)/4) mod p
|
// y mod p = +-(x^3 + 7)^((p+1)/4) mod p
|
||||||
console.log('ECP x=', x.toString(), ' = ', x.toString(16))
|
console.log('ECP x=', x.toString(), ' = ', x.toString(16))
|
||||||
var y = x
|
var y = x.modPow(3, prime).add(7).mod(prime).modPow(pIdent, prime)
|
||||||
.modPow(3, prime)
|
|
||||||
.add(7)
|
|
||||||
.mod(prime)
|
|
||||||
.modPow(pIdent, prime)
|
|
||||||
// If the parity doesn't match it's the *other* root
|
// If the parity doesn't match it's the *other* root
|
||||||
console.log('ECP y=', y.toString(), ' = ', y.toString(16))
|
console.log('ECP y=', y.toString(), ' = ', y.toString(16))
|
||||||
if (y.mod(2).toJSNumber() !== signY) {
|
if (y.mod(2).toJSNumber() !== signY) {
|
||||||
@@ -40,32 +36,17 @@ BigNumber = require('bignumber.js')
|
|||||||
function uncompressPubkey (comp) {
|
function uncompressPubkey (comp) {
|
||||||
// Consts for P256 curve. Adjust accordingly
|
// Consts for P256 curve. Adjust accordingly
|
||||||
const prime = new BigNumber('fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f', 16).integerValue(),
|
const prime = new BigNumber('fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f', 16).integerValue(),
|
||||||
pIdent = prime
|
pIdent = prime.plus(1).idiv(4).integerValue()
|
||||||
.plus(1)
|
|
||||||
.idiv(4)
|
|
||||||
.integerValue()
|
|
||||||
|
|
||||||
console.log('pIdent=', pIdent.toString(), ' = ', pIdent.toString(16))
|
console.log('pIdent=', pIdent.toString(), ' = ', pIdent.toString(16))
|
||||||
var signY = new Number(comp[1]) - 2
|
var signY = new Number(comp[1]) - 2
|
||||||
var x = new BigNumber(comp.substring(2), 16).integerValue()
|
var x = new BigNumber(comp.substring(2), 16).integerValue()
|
||||||
console.log('x=', x.toString(), ' = ', x.toString(16))
|
console.log('x=', x.toString(), ' = ', x.toString(16))
|
||||||
// y^2 = x^3 - 3x + b
|
// y^2 = x^3 - 3x + b
|
||||||
var y = x
|
var y = x.pow(3).mod(prime).plus(7).mod(prime).pow(pIdent).mod(prime).integerValue()
|
||||||
.pow(3)
|
|
||||||
.mod(prime)
|
|
||||||
.plus(7)
|
|
||||||
.mod(prime)
|
|
||||||
.pow(pIdent)
|
|
||||||
.mod(prime)
|
|
||||||
.integerValue()
|
|
||||||
console.log('y=', y.toString(), ' = ', y.toString(16))
|
console.log('y=', y.toString(), ' = ', y.toString(16))
|
||||||
// If the parity doesn't match it's the *other* root
|
// If the parity doesn't match it's the *other* root
|
||||||
if (
|
if (y.mod(2).integerValue().toNumber() !== signY) {
|
||||||
y
|
|
||||||
.mod(2)
|
|
||||||
.integerValue()
|
|
||||||
.toNumber() !== signY
|
|
||||||
) {
|
|
||||||
// y = prime - y
|
// y = prime - y
|
||||||
y = prime.minus(y).integerValue()
|
y = prime.minus(y).integerValue()
|
||||||
}
|
}
|
||||||
@@ -129,10 +110,7 @@ crypto.createCipheriv('aes-256-cfb', Buffer.from(acc.prikey, 'hex'), Buffer.allo
|
|||||||
////////////////////// crypto + PEM
|
////////////////////// crypto + PEM
|
||||||
|
|
||||||
toPEM = function (kp) {
|
toPEM = function (kp) {
|
||||||
let pubkey = crypto
|
let pubkey = crypto.createECDH('secp256k1').setPrivateKey(kp.prikey, 'hex').getPublicKey('hex', 'compressed')
|
||||||
.createECDH('secp256k1')
|
|
||||||
.setPrivateKey(kp.prikey, 'hex')
|
|
||||||
.getPublicKey('hex', 'compressed')
|
|
||||||
console.log('ECDH created publickey = ', pubkey)
|
console.log('ECDH created publickey = ', pubkey)
|
||||||
let mykey = '308187020100301306072a8648ce3d020106082a8648ce3d030107046d306b0201010420' + kp.prikey + 'a144034200' + pubkey
|
let mykey = '308187020100301306072a8648ce3d020106082a8648ce3d030107046d306b0201010420' + kp.prikey + 'a144034200' + pubkey
|
||||||
console.log(mykey)
|
console.log(mykey)
|
||||||
|
|||||||
257
ticc.js
257
ticc.js
@@ -1,10 +1,10 @@
|
|||||||
// const BigNumber=require('bignumber.js') // 处理整数 https://github.com/MikeMcl/bignumber.js
|
// const bignum=require('bignumber.js') // 处理整数 https://github.com/MikeMcl/bignumber.js // size: 360K
|
||||||
const BigInt = require('big-integer') // 处理整数 https://github.com/peterolson/BigInteger.js
|
// const bigint = require('big-integer') // 处理整数 https://github.com/peterolson/BigInteger.js // size: 188K. ethers.js 24M. // 20241005 发现,在 node 控制台里,导入本库命名为 BigInt 后运行 BigInt(xxx) 会导致失败!因为现在已经有 JS 的新 primitive 也叫 BigInt, 不知道作为 server 运行时,怎么没有报错。改名为 bigint
|
||||||
const crypto = require('crypto')
|
const crypto = require('crypto')
|
||||||
const nacl = require('tweetnacl')
|
const nacl = require('tweetnacl')
|
||||||
const bs58check = require('bs58check')
|
const bs58check = require('bs58check')
|
||||||
const bs58 = require('bs58') // bs58check depends on bs58
|
const bs58 = require('bs58') // bs58check depends on bs58
|
||||||
const uuid = require('uuid')
|
//const uuid = require('uuid')
|
||||||
const keccak = require('keccak')
|
const keccak = require('keccak')
|
||||||
const ecc = require('eccrypto-js') // 用于加解密。eccrypto 在 windows 上和 openssl 的版本兼容性有点麻烦,所以换用 eccrypto-js
|
const ecc = require('eccrypto-js') // 用于加解密。eccrypto 在 windows 上和 openssl 的版本兼容性有点麻烦,所以换用 eccrypto-js
|
||||||
const keyman = require('js-crypto-key-utils') // 转换原始密钥和 PER/DER 格式。
|
const keyman = require('js-crypto-key-utils') // 转换原始密钥和 PER/DER 格式。
|
||||||
@@ -16,6 +16,8 @@ const hdkey = require('hdkey') // https://github.com/cryptocoinjs/hdkey // 或
|
|||||||
const secp256k1 = require('secp256k1')
|
const secp256k1 = require('secp256k1')
|
||||||
const base32encode = require('base32-encode')
|
const base32encode = require('base32-encode')
|
||||||
const base32decode = require('base32-decode')
|
const base32decode = require('base32-decode')
|
||||||
|
const ipfsOnlyHash = require('ipfs-only-hash')
|
||||||
|
const { TronWeb } = require('tronweb')
|
||||||
|
|
||||||
// 全部以hex为默认输入输出格式,方便人的阅读,以及方便函数之间统一接口
|
// 全部以hex为默认输入输出格式,方便人的阅读,以及方便函数之间统一接口
|
||||||
|
|
||||||
@@ -124,9 +126,7 @@ class TicCrypto {
|
|||||||
// return false
|
// return false
|
||||||
|
|
||||||
//// for bip39. 注意,bip39对当前defaultWordlist之外其他语言的合法 mnemonic 也返回 false,这一点不如 bitcore-mnemonic. 所以不能直接 bip39.validateMnemonic(secword)
|
//// for bip39. 注意,bip39对当前defaultWordlist之外其他语言的合法 mnemonic 也返回 false,这一点不如 bitcore-mnemonic. 所以不能直接 bip39.validateMnemonic(secword)
|
||||||
secword = secword
|
secword = secword.trim()
|
||||||
.replace(/^\s+/, '') // 删除开头的空格
|
|
||||||
.replace(/\s+$/, '') // 删除末尾的空格
|
|
||||||
if (typeof secword === 'string' && [12, 15, 18, 21, 24].includes(secword.split(/\s+/).length)) {
|
if (typeof secword === 'string' && [12, 15, 18, 21, 24].includes(secword.split(/\s+/).length)) {
|
||||||
if (mode === 'easy') return true // easy模式不检查校验等等严格的合法性了,反正 secword_to_seed 是接受一切字符串的
|
if (mode === 'easy') return true // easy模式不检查校验等等严格的合法性了,反正 secword_to_seed 是接受一切字符串的
|
||||||
if (my.langMap[lang?.toLowerCase?.()]) {
|
if (my.langMap[lang?.toLowerCase?.()]) {
|
||||||
@@ -193,6 +193,7 @@ class TicCrypto {
|
|||||||
* @param {option} [{ hasher = my.HASHER, salt, input = my.INPUT, output = my.OUTPUT }={}]
|
* @param {option} [{ hasher = my.HASHER, salt, input = my.INPUT, output = my.OUTPUT }={}]
|
||||||
* @return {String}
|
* @return {String}
|
||||||
* @memberof TicCrypto
|
* @memberof TicCrypto
|
||||||
|
* 返回结果不包含 0x
|
||||||
*/
|
*/
|
||||||
static hash_easy (data, { hasher = my.HASHER, salt, input = my.INPUT, output = my.OUTPUT } = {}) {
|
static hash_easy (data, { hasher = my.HASHER, salt, input = my.INPUT, output = my.OUTPUT } = {}) {
|
||||||
// data can be anything, but converts to string or remains be Buffer/TypedArray/DataView
|
// data can be anything, but converts to string or remains be Buffer/TypedArray/DataView
|
||||||
@@ -264,9 +265,11 @@ class TicCrypto {
|
|||||||
// data 应当是 encrypt 输出的数据类型
|
// data 应当是 encrypt 输出的数据类型
|
||||||
if (mode === 'ecrsa') {
|
if (mode === 'ecrsa') {
|
||||||
if (key?.prikey && key?.pubkey) {
|
if (key?.prikey && key?.pubkey) {
|
||||||
return ecrsa.decryptMessage(data, key?.prikey, key?.pubkey)
|
return ecrsa.decryptMessage(data, key.prikey, key.pubkey)
|
||||||
|
} else if (key?.receiverPrikey && key?.senderPubkey) {
|
||||||
|
return ecrsa.decryptMessage(data, key.receiverPrikey, key.senderPubkey)
|
||||||
} else {
|
} else {
|
||||||
return ecrsa.decryptMessage(data, key?.receiverPrikey, key?.senderPubkey)
|
return null
|
||||||
}
|
}
|
||||||
} else if (mode === 'ecc') {
|
} else if (mode === 'ecc') {
|
||||||
try {
|
try {
|
||||||
@@ -531,12 +534,15 @@ class TicCrypto {
|
|||||||
return `m/44'/0'/${path}`
|
return `m/44'/0'/${path}`
|
||||||
} else if (coin === 'ETH') {
|
} else if (coin === 'ETH') {
|
||||||
return `m/44'/60'/${path}`
|
return `m/44'/60'/${path}`
|
||||||
|
} else if (coin === 'TRX') {
|
||||||
|
return `m/44'/195'/${path}`
|
||||||
} else if (coin === 'TIC') {
|
} else if (coin === 'TIC') {
|
||||||
return `m/44'/60000'/${path}`
|
return `m/44'/60000'/${path}`
|
||||||
} else if (/[A-Z]{3}/.test(coin)) {
|
} else if (coin === 'MATIC' || coin === 'POL') {
|
||||||
return `m/44'/60${this.alpha_to_digit(coin)}'/${path}`
|
// Polygon 测试网 (Mumbai): 80001
|
||||||
|
return `m/44'/137'/${path}`
|
||||||
} else {
|
} else {
|
||||||
return ''
|
return `m/44'/60${this.alpha_to_digit(coin)}'/${path}`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -576,6 +582,14 @@ class TicCrypto {
|
|||||||
} else if (coin === 'BTC' || coinFamily === 'BTC') {
|
} else if (coin === 'BTC' || coinFamily === 'BTC') {
|
||||||
world = world || 'mainnet'
|
world = world || 'mainnet'
|
||||||
kp.address = this.pubkey_to_address({ pubkey: kp.pubkey, coin, coinFamily, world })
|
kp.address = this.pubkey_to_address({ pubkey: kp.pubkey, coin, coinFamily, world })
|
||||||
|
} else if (coin === 'TRX' || coinFamily === 'TRX') {
|
||||||
|
const prikey = kp.prikey.replace(/^0x/, '') // tronweb 需要去掉开头的 0x
|
||||||
|
const tronweb = new TronWeb({
|
||||||
|
fullHost: 'https://api.trongrid.io',
|
||||||
|
privateKey: prikey,
|
||||||
|
})
|
||||||
|
world = world || 'tron'
|
||||||
|
kp.address = tronweb.address.fromPrivateKey(prikey) // 返回的是带 41 开头的地址
|
||||||
} else {
|
} else {
|
||||||
world = world || my.WORLD
|
world = world || my.WORLD
|
||||||
kp.address = this.pubkey_to_address({ pubkey: kp.pubkey, coin, coinFamily, world })
|
kp.address = this.pubkey_to_address({ pubkey: kp.pubkey, coin, coinFamily, world })
|
||||||
@@ -607,19 +621,19 @@ class TicCrypto {
|
|||||||
* @return {*}
|
* @return {*}
|
||||||
* @memberof TicCrypto
|
* @memberof TicCrypto
|
||||||
*/
|
*/
|
||||||
static prikey_to_pubkey ({ prikey, curve, compress } = {}) {
|
static prikey_to_pubkey ({ prikey, curve, uncompress } = {}) {
|
||||||
if (this.is_prikey({ prikey }) && prikey.length === 64) {
|
if (this.is_prikey({ prikey }) && prikey.length === 64) {
|
||||||
// 只能用于32字节的私钥(BTC, ETH)。也就是不能用于 TIC 的私钥。
|
// 只能用于32字节的私钥(BTC, ETH)。也就是不能用于 TIC 的私钥。
|
||||||
curve = my.CURVE_LIST.includes(curve) ? curve : my.CURVE // 默认为 secp256k1
|
curve = my.CURVE_LIST.includes(curve) ? curve : my.CURVE // 默认为 secp256k1
|
||||||
// return new crypto.createECDH(curve).setPrivateKey(prikey,'hex').getPublicKey('hex', compress===false?'uncompressed':'compressed') // ecdh.getPublicKey(不加参数) 默认为 'compressed'。用 HBuilderX 2.6.4 打包成ios或安卓 app 后 setPrivateKey() 报错:TypeError: null is not an object (evaluating 'this.rand.getBytes')
|
// return new crypto.createECDH(curve).setPrivateKey(prikey,'hex').getPublicKey('hex', uncompress?'uncompressed':'compressed') // ecdh.getPublicKey(不加参数) 默认为 'compressed'。用 HBuilderX 2.6.4 打包成ios或安卓 app 后 setPrivateKey() 报错:TypeError: null is not an object (evaluating 'this.rand.getBytes')
|
||||||
// 从 nodejs 10.0 开始,还有 crypto.ECDH.convertKey 方法,更直接。但可惜,浏览器里不存在 crypto.ECDH。
|
// 从 nodejs 10.0 开始,还有 crypto.ECDH.convertKey 方法,更直接。但可惜,浏览器里不存在 crypto.ECDH。
|
||||||
return this.buf_to_hex(secp256k1.publicKeyCreate(Buffer.from(prikey, 'hex'), compress !== false)) // 可用于浏览器。缺省输出压缩公钥,compress=false时输出非压缩公钥。
|
return this.buf_to_hex(secp256k1.publicKeyCreate(Buffer.from(prikey, 'hex'), !uncompress)) // 可用于浏览器。缺省输出压缩公钥,第二个参数必须正好为false时输出非压缩公钥,为undefined或true时输出压缩公钥,其他时报错。
|
||||||
// 或者 bitcorelib.PublicKey.fromPrivateKey(new bitcorelib.PrivateKey(prikey)).toString('hex') // 可用于浏览器
|
// 或者 bitcorelib.PublicKey.fromPrivateKey(new bitcorelib.PrivateKey(prikey)).toString('hex') // 可用于浏览器
|
||||||
// 或者 const ecc = require('eccrypto')
|
// 或者 const ecc = require('eccrypto')
|
||||||
// if (compress===false){
|
// if (!uncompress){
|
||||||
// return ecc.getPublic(this.hex_to_buf(prikey)).toString('hex')
|
|
||||||
// }else{
|
|
||||||
// return ecc.getPublicCompressed(this.hex_to_buf(prikey)).toString('hex')
|
// return ecc.getPublicCompressed(this.hex_to_buf(prikey)).toString('hex')
|
||||||
|
// } else{
|
||||||
|
// return ecc.getPublic(this.hex_to_buf(prikey)).toString('hex')
|
||||||
// }
|
// }
|
||||||
// 注意,Buffer.from(nacl.box.keyPair.fromSecretKey(Buffer.from(prikey,'hex')).publicKey).toString('hex') 得到的公钥与上面的不同
|
// 注意,Buffer.from(nacl.box.keyPair.fromSecretKey(Buffer.from(prikey,'hex')).publicKey).toString('hex') 得到的公钥与上面的不同
|
||||||
} else if (this.is_prikey({ prikey }) && prikey.length === 128) {
|
} else if (this.is_prikey({ prikey }) && prikey.length === 128) {
|
||||||
@@ -644,11 +658,12 @@ class TicCrypto {
|
|||||||
if (this.is_prikey({ prikey })) {
|
if (this.is_prikey({ prikey })) {
|
||||||
/** @type {*} */
|
/** @type {*} */
|
||||||
let pubkey
|
let pubkey
|
||||||
if (coin === 'ETH') {
|
if (coin === 'ETH' || coinFamily === 'ETH') {
|
||||||
pubkey = this.prikey_to_pubkey({ prikey, compress: false })
|
pubkey = this.prikey_to_pubkey({ prikey, uncompress: true })
|
||||||
return this.pubkey_to_address({ pubkey, coin, coinFamily, world })
|
return this.pubkey_to_address({ pubkey, coin, coinFamily, world })
|
||||||
|
// 实际上发现,不论是否 compressed,最后转成的地址都是一样的,因为在 pubkey_to_position 里已经自动处理了。
|
||||||
} else {
|
} else {
|
||||||
pubkey = this.prikey_to_pubkey({ prikey, compress: true })
|
pubkey = this.prikey_to_pubkey({ prikey, uncompress: false })
|
||||||
return this.pubkey_to_address({ pubkey, coin, coinFamily, world })
|
return this.pubkey_to_address({ pubkey, coin, coinFamily, world })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -920,7 +935,7 @@ class TicCrypto {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let prikey = this.randomize_seckey()
|
let prikey = this.randomize_seckey()
|
||||||
let pubkey = this.prikey_to_pubkey({ prikey })
|
let pubkey = this.prikey_to_pubkey({ prikey, uncompress: false })
|
||||||
return {
|
return {
|
||||||
prikey,
|
prikey,
|
||||||
pubkey,
|
pubkey,
|
||||||
@@ -973,6 +988,17 @@ class TicCrypto {
|
|||||||
return text
|
return text
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static randomize_hex ({ length = 64 } = {}) {
|
||||||
|
// 长度为 length 的随机 hex 字符串。注意 randomBytes 在一些环境里可能不存在,例如在 HBuilderX 的内置浏览器里。
|
||||||
|
if (crypto.randomBytes) {
|
||||||
|
return crypto
|
||||||
|
.randomBytes(Math.ceil(length / 2))
|
||||||
|
.toString('hex')
|
||||||
|
.slice(0, length)
|
||||||
|
}
|
||||||
|
return this.randomize_string({ length, alphabet: '0123456789abcdef' })
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 生成随机的数字
|
* 生成随机的数字
|
||||||
*
|
*
|
||||||
@@ -1023,7 +1049,7 @@ class TicCrypto {
|
|||||||
* @memberof TicCrypto
|
* @memberof TicCrypto
|
||||||
*/
|
*/
|
||||||
static randomize_uuid () {
|
static randomize_uuid () {
|
||||||
return uuid.v4()
|
return crypto.randomUUID() // uuid.v4()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1097,7 +1123,8 @@ class TicCrypto {
|
|||||||
// hash为64hex字符,sig为128hex字符。返回用hex表达的距离。
|
// hash为64hex字符,sig为128hex字符。返回用hex表达的距离。
|
||||||
if (this.is_signature({ sig: sig }) && this.is_hash({ hash })) {
|
if (this.is_signature({ sig: sig }) && this.is_hash({ hash })) {
|
||||||
var hashSig = this.hash_easy(sig) // 把签名也转成32字节的哈希,同样长度方便比较
|
var hashSig = this.hash_easy(sig) // 把签名也转成32字节的哈希,同样长度方便比较
|
||||||
return (BigInt('0x' + hash) - BigInt('0x' + hashSig)).toString(16).replace(/^-/, '')
|
// 20241005 注意到,原来通过 require('big-integer') 进行直接减法,可能是错误的!换用原生 BigInt 配合直接减法。
|
||||||
|
return (BigInt('0x' + hash) - BigInt('0x' + hashSig)).toString(16).replace(/^-/, '') // if using bignumber.js: (bignum('0x' + hash) - bignum('0x' + hashSig)).toString(16)
|
||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
@@ -1271,7 +1298,7 @@ class TicCrypto {
|
|||||||
try {
|
try {
|
||||||
return bs58check.encode(Buffer.from(hex, 'hex'))
|
return bs58check.encode(Buffer.from(hex, 'hex'))
|
||||||
} catch (exception) {
|
} catch (exception) {
|
||||||
return null
|
return ''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1279,7 +1306,7 @@ class TicCrypto {
|
|||||||
try {
|
try {
|
||||||
return bs58.encode(Buffer.from(hex, 'hex'))
|
return bs58.encode(Buffer.from(hex, 'hex'))
|
||||||
} catch (exception) {
|
} catch (exception) {
|
||||||
return null
|
return ''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1295,7 +1322,7 @@ class TicCrypto {
|
|||||||
try {
|
try {
|
||||||
return bs58check.decode(box).toString('hex')
|
return bs58check.decode(box).toString('hex')
|
||||||
} catch (exception) {
|
} catch (exception) {
|
||||||
return null
|
return ''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1303,7 +1330,7 @@ class TicCrypto {
|
|||||||
try {
|
try {
|
||||||
return bs58.decode(box).toString('hex')
|
return bs58.decode(box).toString('hex')
|
||||||
} catch (exception) {
|
} catch (exception) {
|
||||||
return null
|
return ''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1332,10 +1359,10 @@ class TicCrypto {
|
|||||||
* @memberof TicCrypto
|
* @memberof TicCrypto
|
||||||
*/
|
*/
|
||||||
static hex_to_b64t (hex) {
|
static hex_to_b64t (hex) {
|
||||||
if (/^[0-9a-fA-F]+$/.test(hex)) {
|
if (my.REGEXP_ALPHABET.hex.test(hex)) {
|
||||||
return this.b64_to_b64t(Buffer.from(hex, 'hex').toString('base64'))
|
return this.b64_to_b64t(Buffer.from(hex, 'hex').toString('base64'))
|
||||||
}
|
}
|
||||||
return null
|
return ''
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1347,36 +1374,36 @@ class TicCrypto {
|
|||||||
* @memberof TicCrypto
|
* @memberof TicCrypto
|
||||||
*/
|
*/
|
||||||
static b64t_to_hex (b64t) {
|
static b64t_to_hex (b64t) {
|
||||||
if (/^[0-9a-zA-Z\._]+$/.test(b64t)) {
|
if (my.REGEXP_ALPHABET.b64t.test(b64t)) {
|
||||||
return Buffer.from(this.b64t_to_b64(b64t), 'base64').toString('hex')
|
return Buffer.from(this.b64t_to_b64(b64t), 'base64').toString('hex')
|
||||||
}
|
}
|
||||||
return null
|
return ''
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://en.wikipedia.org/wiki/Base32
|
// https://en.wikipedia.org/wiki/Base32
|
||||||
static hex_to_b32 (hex) {
|
static hex_to_b32 (hex) {
|
||||||
if (/^[0-9a-fA-F]+$/.test(hex)) {
|
if (my.REGEXP_ALPHABET.hex.test(hex)) {
|
||||||
return base32encode(Buffer.from(hex, 'hex'), 'RFC4648')
|
return base32encode(Buffer.from(hex, 'hex'), 'RFC4648')
|
||||||
}
|
}
|
||||||
return null
|
return ''
|
||||||
}
|
}
|
||||||
static b32_to_hex (b32) {
|
static b32_to_hex (b32) {
|
||||||
if (/^[A-Za-z2-7=]+$/.test(b32)) {
|
if (my.REGEXP_ALPHABET.b32.test(b32)) {
|
||||||
return Buffer.from(base32decode(b32.toUpperCase(), 'RFC4648')).toString('hex')
|
return Buffer.from(base32decode(b32.toUpperCase(), 'RFC4648')).toString('hex')
|
||||||
}
|
}
|
||||||
return null
|
return ''
|
||||||
}
|
}
|
||||||
static hex_to_b32h (hex) {
|
static hex_to_b32h (hex) {
|
||||||
if (/^[0-9a-fA-F]+$/.test(hex)) {
|
if (my.REGEXP_ALPHABET.hex.test(hex)) {
|
||||||
return base32encode(Buffer.from(hex, 'hex'), 'RFC4648-HEX')
|
return base32encode(Buffer.from(hex, 'hex'), 'RFC4648-HEX')
|
||||||
}
|
}
|
||||||
return null
|
return ''
|
||||||
}
|
}
|
||||||
static b32h_to_hex (b32h) {
|
static b32h_to_hex (b32h) {
|
||||||
if (/^[0-9A-Va-v=]+$/.test(b32h)) {
|
if (my.REGEXP_ALPHABET.b32h.test(b32h)) {
|
||||||
return Buffer.from(base32decode(b32.toUpperCase(), 'RFC4648-HEX')).toString('hex')
|
return Buffer.from(base32decode(b32.toUpperCase(), 'RFC4648-HEX')).toString('hex')
|
||||||
}
|
}
|
||||||
return null
|
return ''
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1401,14 +1428,14 @@ class TicCrypto {
|
|||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
return null
|
return ''
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 压缩公钥
|
* 压缩公钥
|
||||||
*
|
*
|
||||||
* @static
|
* @static
|
||||||
* @param {*} uncompressed
|
* @param {*} uncompressed: strings like '0x1234567890abcedf...'
|
||||||
* @return {*}
|
* @return {*}
|
||||||
* @memberof TicCrypto
|
* @memberof TicCrypto
|
||||||
*/
|
*/
|
||||||
@@ -1418,7 +1445,7 @@ class TicCrypto {
|
|||||||
// 把 04xy 的非压缩公钥 转成 02x 或 03x 的压缩公钥
|
// 把 04xy 的非压缩公钥 转成 02x 或 03x 的压缩公钥
|
||||||
let [all, x, y] = uncompressed.toLowerCase().match(/^04(.{64})(.{64})$/)
|
let [all, x, y] = uncompressed.toLowerCase().match(/^04(.{64})(.{64})$/)
|
||||||
let compressed
|
let compressed
|
||||||
if (/[1,3,5,7,9,b,d,f]$/.test(y)) {
|
if (/[13579bdf]$/.test(y)) {
|
||||||
compressed = '03' + x // y为奇数=>前缀03
|
compressed = '03' + x // y为奇数=>前缀03
|
||||||
} else {
|
} else {
|
||||||
compressed = '02' + x // y为偶数=>前缀02
|
compressed = '02' + x // y为偶数=>前缀02
|
||||||
@@ -1426,7 +1453,57 @@ class TicCrypto {
|
|||||||
if (this.decompress_pubkey(compressed) === uncompressed) {
|
if (this.decompress_pubkey(compressed) === uncompressed) {
|
||||||
return compressed
|
return compressed
|
||||||
}
|
}
|
||||||
return null // 非压缩公钥有错误。
|
return '' // 非压缩公钥有错误。
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* decompress_pubkey 需要用到 big-integer 的 modPow 方法。如果想用原生的 BigInt,就需要自己实现 modPow
|
||||||
|
* @param {*} base
|
||||||
|
* @param {*} exponent
|
||||||
|
* @param {*} modulus
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
static modPow (base, exponent, modulus) {
|
||||||
|
let result = BigInt(1)
|
||||||
|
base = BigInt(base)
|
||||||
|
exponent = BigInt(exponent)
|
||||||
|
modulus = BigInt(modulus)
|
||||||
|
|
||||||
|
while (exponent > 0n) {
|
||||||
|
if (exponent & BigInt(1)) {
|
||||||
|
result = (result * base) % modulus
|
||||||
|
}
|
||||||
|
base = (base * base) % modulus
|
||||||
|
exponent = exponent >> BigInt(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解压缩公钥
|
||||||
|
*
|
||||||
|
* @static
|
||||||
|
* @param {*} compressed: strings like '020123456789abcdef...'
|
||||||
|
* @return {*}
|
||||||
|
* @memberof TicCrypto
|
||||||
|
*/
|
||||||
|
static decompress_pubkey (compressed = '') {
|
||||||
|
// uncompress: https://stackoverflow.com/questions/17171542/algorithm-for-elliptic-curve-point-compression/53478265#53478265
|
||||||
|
// https://en.bitcoin.it/wiki/Secp256k1
|
||||||
|
// 把 02x 或 03x 的压缩公钥 转成 04xy 的非压缩公钥
|
||||||
|
// Consts for secp256k1 curve. Adjust accordingly
|
||||||
|
const prime = BigInt('0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f', 16) // 2^256 - 2^32 - 2^9 - 2^8 - 2^7 - 2^6 - 2^4 - 1
|
||||||
|
const pIdent = BigInt('0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff0c', 16) // prime.add(1).divide(4);
|
||||||
|
var signY = BigInt(Number(compressed[1]) - 2)
|
||||||
|
var x = BigInt('0x' + compressed.substr(2))
|
||||||
|
var y = this.modPow((this.modPow(x, 3, prime) + BigInt(7)) % prime, pIdent, prime) // y mod p = +-(x^3 + 7)^((p+1)/4) mod p
|
||||||
|
if (y % BigInt(2) !== signY) {
|
||||||
|
// If the parity doesn't match it's the *other* root
|
||||||
|
y = prime - y
|
||||||
|
}
|
||||||
|
return '04' + this.padStart(x.toString(16), 64, '0') + this.padStart(y.toString(16), 64, '0')
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1437,16 +1514,12 @@ class TicCrypto {
|
|||||||
* @return {*}
|
* @return {*}
|
||||||
* @memberof TicCrypto
|
* @memberof TicCrypto
|
||||||
*/
|
*/
|
||||||
static decompress_pubkey (compressed) {
|
static decompress_pubkey_bigint (compressed) {
|
||||||
// uncompress: https://stackoverflow.com/questions/17171542/algorithm-for-elliptic-curve-point-compression/53478265#53478265
|
const bigint = globalThis.bigint || require('big-integer')
|
||||||
// https://en.bitcoin.it/wiki/Secp256k1
|
const prime = bigint('fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f', 16) // 2^256 - 2^32 - 2^9 - 2^8 - 2^7 - 2^6 - 2^4 - 1
|
||||||
// 把 02x 或 03x 的压缩公钥 转成 04xy 的非压缩公钥
|
const pIdent = bigint('3fffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff0c', 16) // prime.add(1).divide(4);
|
||||||
// Consts for secp256k1 curve. Adjust accordingly
|
|
||||||
const prime = new BigInt('fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f', 16) // 2^256 - 2^32 - 2^9 - 2^8 - 2^7 - 2^6 - 2^4 - 1
|
|
||||||
const pIdent = new BigInt('3fffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff0c', 16) // prime.add(1).divide(4);
|
|
||||||
var signY = new Number(compressed[1]) - 2
|
var signY = new Number(compressed[1]) - 2
|
||||||
var x = new BigInt(compressed.substr(2), 16)
|
var x = bigint(compressed.substr(2), 16)
|
||||||
// 需要用到 big-integer 的 modPow 方法。如果直接用原生的 BigInt 会 "Maximum BigInt size exceeded"
|
|
||||||
var y = x.modPow(3, prime).add(7).mod(prime).modPow(pIdent, prime) // y mod p = +-(x^3 + 7)^((p+1)/4) mod p
|
var y = x.modPow(3, prime).add(7).mod(prime).modPow(pIdent, prime) // y mod p = +-(x^3 + 7)^((p+1)/4) mod p
|
||||||
if (y.mod(2).toJSNumber() !== signY) {
|
if (y.mod(2).toJSNumber() !== signY) {
|
||||||
// If the parity doesn't match it's the *other* root
|
// If the parity doesn't match it's the *other* root
|
||||||
@@ -1455,19 +1528,34 @@ class TicCrypto {
|
|||||||
return '04' + this.padStart(x.toString(16), 64, '0') + this.padStart(y.toString(16), 64, '0')
|
return '04' + this.padStart(x.toString(16), 64, '0') + this.padStart(y.toString(16), 64, '0')
|
||||||
}
|
}
|
||||||
|
|
||||||
static cid_to_cosh ({ cid }) {
|
static async content_to_cid ({ content, ...option }) {
|
||||||
if (/^[Q|1]/.test(cid)) {
|
// {content: 'hello world', cidVersion: 0}
|
||||||
return this.b58_to_hex(cid).slice(4)
|
// content can be a string, a file, a stream
|
||||||
} else if (/^[b|B]/.test(cid)) {
|
return await ipfsOnlyHash.of(content, option)
|
||||||
return this.b32_to_hex(cid.substr(1)).slice(8)
|
}
|
||||||
|
|
||||||
|
// cahex: content address hex. 最核心的纯hex的内容地址,没有任何额外标记。同一个内容的 cahex 是唯一的,而 cid 是在 cahex 基础上有各种不同的编码,转成字符串形式。cid建议叫做 caid.
|
||||||
|
static cid_to_cahex ({ cid }) {
|
||||||
|
try {
|
||||||
|
if (/^[Q1]/.test(cid)) {
|
||||||
|
return this.b58_to_hex(cid).slice(4) // 前2字节是 cid0 的字节序数标记
|
||||||
|
} else if (/^[bB]/.test(cid)) {
|
||||||
|
return this.b32_to_hex(cid.substr(1)).slice(8) // 前4字节是 cid1 的标记
|
||||||
} else if (/^z/.test(cid)) {
|
} else if (/^z/.test(cid)) {
|
||||||
return this.b58_to_hex(cid.substr(1)).slice(8)
|
return this.b58_to_hex(cid.substr(1)).slice(8)
|
||||||
} else if (/^[m|M|u|U]/.test(cid)) {
|
} else if (/^[mMuU]/.test(cid)) {
|
||||||
return Buffer.from(cid.substr(1), 'base64').toString('hex')
|
return Buffer.from(cid.substr(1), 'base64').toString('hex')
|
||||||
|
} else if (/^[fF]/) {
|
||||||
|
return cid.substr(9).toLowerCase()
|
||||||
|
} else if (/^9/.test(cid)) {
|
||||||
|
return BigInt(cid.slice(1)).toString(16).slice(7) // toString(16) 后,去掉了 01551220... 的打头的 0,所以只有7位需要跳过了
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
return ''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static cosh_to_cid ({ cosh, cidBase = 'b32', cidVersion = 1, cidCodec = 'raw', cidAlgo = 'sha256' }) {
|
static cahex_to_cid ({ cahex, cidBase = 'b32', cidVersion = 1, cidCodec = 'raw', cidAlgo = 'sha256' }) {
|
||||||
// https://github.com/multiformats/multibase
|
// https://github.com/multiformats/multibase
|
||||||
const multibase = {
|
const multibase = {
|
||||||
identity: 0x00,
|
identity: 0x00,
|
||||||
@@ -1507,23 +1595,64 @@ class TicCrypto {
|
|||||||
ripemd160: '1053',
|
ripemd160: '1053',
|
||||||
md5: 'd5',
|
md5: 'd5',
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
if (cidVersion === 0) {
|
if (cidVersion === 0) {
|
||||||
return this.hex_to_b58(`${multialgo[cidAlgo]}${Number(cosh.length / 2).toString(16)}${cosh}`)
|
return this.hex_to_b58(`${multialgo[cidAlgo]}${Number(cahex.length / 2).toString(16)}${cahex}`)
|
||||||
} else if (cidVersion === 1) {
|
} else if (cidVersion === 1) {
|
||||||
const fullHex = `01${multicodec[cidCodec]}${multialgo[cidAlgo]}${Number(cosh.length / 2).toString(16)}${cosh}`
|
const fullHex = `01${multicodec[cidCodec]}${multialgo[cidAlgo]}${Number(cahex.length / 2).toString(16)}${cahex}`
|
||||||
let converted = ''
|
let converted = ''
|
||||||
if (cidBase === 'b32') {
|
if (cidBase === 'b16') {
|
||||||
converted = this.hex_to_b32(fullHex).toLowerCase().replace(/=/g, '')
|
converted = fullHex.toLowerCase()
|
||||||
|
} else if (cidBase === 'B16') {
|
||||||
|
converted = fullHex.toUpperCase()
|
||||||
|
} else if (cidBase === 'b32') {
|
||||||
|
converted = this.hex_to_b32(fullHex)?.toLowerCase?.()?.replace?.(/=/g, '')
|
||||||
} else if (cidBase === 'B32') {
|
} else if (cidBase === 'B32') {
|
||||||
converted = this.hex_to_b32(fullHex).toUpperCase().replace(/=/g, '')
|
converted = this.hex_to_b32(fullHex)?.toUpperCase?.()?.replace?.(/=/g, '')
|
||||||
} else if (cidBase === 'b58') {
|
} else if (cidBase === 'b58') {
|
||||||
converted = this.hex_to_b58(fullHex)
|
converted = this.hex_to_b58(fullHex)
|
||||||
} else if (cidBase === 'b64p') {
|
} else if (cidBase === 'b64p') {
|
||||||
converted = Buffer.from(fullHex, 'hex').toString('base64')
|
converted = Buffer.from(fullHex, 'hex').toString('base64')
|
||||||
} else if (cidBase === 'b64') {
|
} else if (cidBase === 'b64') {
|
||||||
converted = Buffer.from(fullHex, 'hex').toString('base64').replace(/=/g, '')
|
converted = Buffer.from(fullHex, 'hex').toString('base64').replace(/=/g, '')
|
||||||
|
} else if (cidBase === 'b10') {
|
||||||
|
converted = BigInt('0x' + fullHex).toString()
|
||||||
}
|
}
|
||||||
|
if (converted) {
|
||||||
return multibase[cidBase] + converted
|
return multibase[cidBase] + converted
|
||||||
|
} else {
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static convert_pexid (key) {
|
||||||
|
key = key.toLowerCase()
|
||||||
|
let pextokenCid, pextokenCahex, nftToid, tokenURI
|
||||||
|
try {
|
||||||
|
if (key.length < 64 && /^bafkrei/.test(key)) {
|
||||||
|
pextokenCid = key
|
||||||
|
pextokenCahex = this.cid_to_cahex({ cid: pextokenCid })
|
||||||
|
nftToid = BigInt('0x' + pextokenCahex).toString()
|
||||||
|
} else if (key.length > 64 && /^\d+$/.test(key)) {
|
||||||
|
nftToid = key
|
||||||
|
pextokenCahex = BigInt(nftToid).toString(16)
|
||||||
|
pextokenCid = this.cahex_to_cid({ cahex: pextokenCahex })
|
||||||
|
} else if (/^[0-9a-f]{64}$/.test(key)) {
|
||||||
|
pextokenCahex = key
|
||||||
|
pextokenCid = this.cahex_to_cid({ cahex: pextokenCahex })
|
||||||
|
nftToid = BigInt('0x' + pextokenCahex).toString()
|
||||||
|
}
|
||||||
|
tokenURI = pextokenCahex ? `https://ipfs.tic.cc/ipfs/f01551220${pextokenCahex}` : undefined
|
||||||
|
} catch {}
|
||||||
|
return {
|
||||||
|
pextokenCid,
|
||||||
|
pextokenCahex,
|
||||||
|
nftToid,
|
||||||
|
tokenURI,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user