--- /dev/null
+package io.bytom.api;\r
+\r
+import io.bytom.common.DeriveXpub;\r
+\r
+import java.security.InvalidKeyException;\r
+import java.security.MessageDigest;\r
+import java.security.NoSuchAlgorithmException;\r
+import java.security.SignatureException;\r
+import java.util.Arrays;\r
+\r
+public class Signer {\r
+\r
+ public static byte[] Ed25519InnerSign(byte[] privateKey, byte[] message)\r
+ throws SignatureException, NoSuchAlgorithmException, InvalidKeyException {\r
+ MessageDigest md = MessageDigest.getInstance("SHA-512");\r
+ byte[] digestData = new byte[32 + message.length];\r
+ int digestDataIndex = 0;\r
+ for (int i = 32; i < 64; i++) {\r
+ digestData[digestDataIndex] = privateKey[i];\r
+ digestDataIndex++;\r
+ }\r
+ for (int i = 0; i < message.length; i++) {\r
+ digestData[digestDataIndex] = message[i];\r
+ digestDataIndex++;\r
+ }\r
+ md.update(digestData);\r
+ byte[] messageDigest = md.digest();\r
+\r
+ com.google.crypto.tink.subtle.Ed25519.reduce(messageDigest);\r
+ byte[] messageDigestReduced = Arrays.copyOfRange(messageDigest, 0, 32);\r
+ byte[] encodedR = com.google.crypto.tink.subtle.Ed25519.scalarMultWithBaseToBytes(messageDigestReduced);\r
+ byte[] publicKey = DeriveXpub.deriveXpub(privateKey);\r
+\r
+ byte[] hramDigestData = new byte[32 + encodedR.length + message.length];\r
+ int hramDigestIndex = 0;\r
+ for (int i = 0; i < encodedR.length; i++) {\r
+ hramDigestData[hramDigestIndex] = encodedR[i];\r
+ hramDigestIndex++;\r
+ }\r
+ for (int i = 0; i < 32; i++) {\r
+ hramDigestData[hramDigestIndex] = publicKey[i];\r
+ hramDigestIndex++;\r
+ }\r
+ for (int i = 0; i < message.length; i++) {\r
+ hramDigestData[hramDigestIndex] = message[i];\r
+ hramDigestIndex++;\r
+ }\r
+ md.reset();\r
+ md.update(hramDigestData);\r
+ byte[] hramDigest = md.digest();\r
+ com.google.crypto.tink.subtle.Ed25519.reduce(hramDigest);\r
+ byte[] hramDigestReduced = Arrays.copyOfRange(hramDigest, 0, 32);\r
+\r
+ byte[] sk = Arrays.copyOfRange(privateKey, 0, 32);\r
+ byte[] s = new byte[32];\r
+ com.google.crypto.tink.subtle.Ed25519.mulAdd(s, hramDigestReduced, sk, messageDigestReduced);\r
+\r
+ byte[] signature = new byte[64];\r
+ for (int i = 0; i < encodedR.length; i++) {\r
+ signature[i] = encodedR[i];\r
+ }\r
+ int signatureIndex = 32;\r
+ for (int i = 0; i < s.length; i++) {\r
+ signature[signatureIndex] = s[i];\r
+ signatureIndex++;\r
+ }\r
+ return signature;\r
+ }\r
+\r
+}\r