@authon/react-native-wallet 0.0.0-stage → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (183) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/README.md +251 -2
  3. package/android/build.gradle +40 -0
  4. package/android/consumer-rules.pro +10 -0
  5. package/android/src/main/AndroidManifest.xml +8 -0
  6. package/android/src/main/java/dev/authon/reactnative/wallet/AuthonWalletModule.kt +235 -0
  7. package/android/src/vendor/GENERATED.md +4 -0
  8. package/android/src/vendor/kotlin/dev/authon/sdk/wallet/AndroidCapabilityProbe.kt +86 -0
  9. package/android/src/vendor/kotlin/dev/authon/sdk/wallet/AuthonWallet.kt +218 -0
  10. package/android/src/vendor/kotlin/dev/authon/sdk/wallet/Bitcoin.kt +296 -0
  11. package/android/src/vendor/kotlin/dev/authon/sdk/wallet/Bytes.kt +74 -0
  12. package/android/src/vendor/kotlin/dev/authon/sdk/wallet/Chains.kt +157 -0
  13. package/android/src/vendor/kotlin/dev/authon/sdk/wallet/CredentialManagerPasskeys.kt +192 -0
  14. package/android/src/vendor/kotlin/dev/authon/sdk/wallet/Der.kt +17 -0
  15. package/android/src/vendor/kotlin/dev/authon/sdk/wallet/DeviceStore.kt +170 -0
  16. package/android/src/vendor/kotlin/dev/authon/sdk/wallet/DialogWalletApprover.kt +141 -0
  17. package/android/src/vendor/kotlin/dev/authon/sdk/wallet/Eip712.kt +176 -0
  18. package/android/src/vendor/kotlin/dev/authon/sdk/wallet/Encodings.kt +133 -0
  19. package/android/src/vendor/kotlin/dev/authon/sdk/wallet/EvmAccount.kt +45 -0
  20. package/android/src/vendor/kotlin/dev/authon/sdk/wallet/EvmTransaction.kt +180 -0
  21. package/android/src/vendor/kotlin/dev/authon/sdk/wallet/GfTables.kt +44 -0
  22. package/android/src/vendor/kotlin/dev/authon/sdk/wallet/HdWallet.kt +130 -0
  23. package/android/src/vendor/kotlin/dev/authon/sdk/wallet/Http.kt +86 -0
  24. package/android/src/vendor/kotlin/dev/authon/sdk/wallet/JsValues.kt +83 -0
  25. package/android/src/vendor/kotlin/dev/authon/sdk/wallet/KeystoreDeviceStore.kt +236 -0
  26. package/android/src/vendor/kotlin/dev/authon/sdk/wallet/Prf.kt +111 -0
  27. package/android/src/vendor/kotlin/dev/authon/sdk/wallet/Proof.kt +134 -0
  28. package/android/src/vendor/kotlin/dev/authon/sdk/wallet/Shamir.kt +106 -0
  29. package/android/src/vendor/kotlin/dev/authon/sdk/wallet/SignSummary.kt +335 -0
  30. package/android/src/vendor/kotlin/dev/authon/sdk/wallet/Solana.kt +195 -0
  31. package/android/src/vendor/kotlin/dev/authon/sdk/wallet/Tron.kt +184 -0
  32. package/android/src/vendor/kotlin/dev/authon/sdk/wallet/WalletApi.kt +361 -0
  33. package/android/src/vendor/kotlin/dev/authon/sdk/wallet/WalletCapabilities.kt +91 -0
  34. package/android/src/vendor/kotlin/dev/authon/sdk/wallet/WalletError.kt +74 -0
  35. package/android/src/vendor/kotlin/dev/authon/sdk/wallet/WalletOps.kt +551 -0
  36. package/android/src/vendor/kotlin/dev/authon/sdk/wallet/WalletTypes.kt +78 -0
  37. package/android/src/vendor/kotlin/dev/authon/sdk/wallet/Xrp.kt +193 -0
  38. package/build/authonContext.d.ts +19 -0
  39. package/build/authonContext.d.ts.map +1 -0
  40. package/build/authonContext.js +20 -0
  41. package/build/authonContext.js.map +1 -0
  42. package/build/client.d.ts +92 -0
  43. package/build/client.d.ts.map +1 -0
  44. package/build/client.js +431 -0
  45. package/build/client.js.map +1 -0
  46. package/build/errors.d.ts +25 -0
  47. package/build/errors.d.ts.map +1 -0
  48. package/build/errors.js +15 -0
  49. package/build/errors.js.map +1 -0
  50. package/build/index.d.ts +7 -0
  51. package/build/index.d.ts.map +1 -0
  52. package/build/index.js +4 -0
  53. package/build/index.js.map +1 -0
  54. package/build/native.d.ts +43 -0
  55. package/build/native.d.ts.map +1 -0
  56. package/build/native.js +12 -0
  57. package/build/native.js.map +1 -0
  58. package/build/types.d.ts +167 -0
  59. package/build/types.d.ts.map +1 -0
  60. package/build/types.js +3 -0
  61. package/build/types.js.map +1 -0
  62. package/build/useAuthonWallet.d.ts +25 -0
  63. package/build/useAuthonWallet.d.ts.map +1 -0
  64. package/build/useAuthonWallet.js +77 -0
  65. package/build/useAuthonWallet.js.map +1 -0
  66. package/expo-module.config.json +9 -0
  67. package/ios/AuthonReactNativeWallet.podspec +41 -0
  68. package/ios/AuthonWalletModule.swift +233 -0
  69. package/ios/vendor/AuthonWallet/AuthonWallet.swift +232 -0
  70. package/ios/vendor/AuthonWallet/Capabilities.swift +149 -0
  71. package/ios/vendor/AuthonWallet/Chains/Bitcoin.swift +296 -0
  72. package/ios/vendor/AuthonWallet/Chains/Solana.swift +207 -0
  73. package/ios/vendor/AuthonWallet/Chains/Tron.swift +181 -0
  74. package/ios/vendor/AuthonWallet/Chains/XRP.swift +191 -0
  75. package/ios/vendor/AuthonWallet/Crypto/BIP39Wordlist.swift +262 -0
  76. package/ios/vendor/AuthonWallet/Crypto/Chains.swift +278 -0
  77. package/ios/vendor/AuthonWallet/Crypto/HDKey.swift +108 -0
  78. package/ios/vendor/AuthonWallet/Crypto/Secp256k1.swift +128 -0
  79. package/ios/vendor/AuthonWallet/Crypto/Shamir.swift +123 -0
  80. package/ios/vendor/AuthonWallet/EVM/Address.swift +57 -0
  81. package/ios/vendor/AuthonWallet/EVM/EvmAccount.swift +48 -0
  82. package/ios/vendor/AuthonWallet/EVM/Transaction.swift +165 -0
  83. package/ios/vendor/AuthonWallet/EVM/TypedData.swift +193 -0
  84. package/ios/vendor/AuthonWallet/Support/BigInteger.swift +220 -0
  85. package/ios/vendor/AuthonWallet/Support/Bytes.swift +89 -0
  86. package/ios/vendor/AuthonWallet/Support/JSONValue.swift +341 -0
  87. package/ios/vendor/AuthonWallet/UI/WalletApprover.swift +250 -0
  88. package/ios/vendor/AuthonWallet/Wallet/Backup.swift +69 -0
  89. package/ios/vendor/AuthonWallet/Wallet/DeviceStore.swift +351 -0
  90. package/ios/vendor/AuthonWallet/Wallet/Passkeys.swift +190 -0
  91. package/ios/vendor/AuthonWallet/Wallet/Proof.swift +143 -0
  92. package/ios/vendor/AuthonWallet/Wallet/Shares.swift +116 -0
  93. package/ios/vendor/AuthonWallet/Wallet/Summary.swift +342 -0
  94. package/ios/vendor/AuthonWallet/Wallet/WalletAPI.swift +361 -0
  95. package/ios/vendor/AuthonWallet/Wallet/WalletOps.swift +654 -0
  96. package/ios/vendor/AuthonWallet/WalletError.swift +84 -0
  97. package/ios/vendor/CKeccak/LICENSE +22 -0
  98. package/ios/vendor/CKeccak/README.md +30 -0
  99. package/ios/vendor/CKeccak/byte_order.h +59 -0
  100. package/ios/vendor/CKeccak/include/ckeccak.h +13 -0
  101. package/ios/vendor/CKeccak/memzero.c +75 -0
  102. package/ios/vendor/CKeccak/memzero.h +8 -0
  103. package/ios/vendor/CKeccak/options.h +99 -0
  104. package/ios/vendor/CKeccak/ripemd160.c +343 -0
  105. package/ios/vendor/CKeccak/ripemd160.h +22 -0
  106. package/ios/vendor/CKeccak/sha3.c +413 -0
  107. package/ios/vendor/CKeccak/sha3.h +89 -0
  108. package/ios/vendor/CMonocypher/LICENCE.md +173 -0
  109. package/ios/vendor/CMonocypher/README.md +27 -0
  110. package/ios/vendor/CMonocypher/include/monocypher-ed25519.h +140 -0
  111. package/ios/vendor/CMonocypher/include/monocypher.h +321 -0
  112. package/ios/vendor/CMonocypher/monocypher-ed25519.c +500 -0
  113. package/ios/vendor/CMonocypher/monocypher.c +2956 -0
  114. package/ios/vendor/CSecp256k1/COPYING +19 -0
  115. package/ios/vendor/CSecp256k1/README.md +35 -0
  116. package/ios/vendor/CSecp256k1/build/precomputed_ecmult.c +3 -0
  117. package/ios/vendor/CSecp256k1/build/precomputed_ecmult_gen.c +3 -0
  118. package/ios/vendor/CSecp256k1/build/secp256k1.c +3 -0
  119. package/ios/vendor/CSecp256k1/include/secp256k1.h +899 -0
  120. package/ios/vendor/CSecp256k1/include/secp256k1_preallocated.h +134 -0
  121. package/ios/vendor/CSecp256k1/include/secp256k1_recovery.h +113 -0
  122. package/ios/vendor/CSecp256k1/src/assumptions.h +87 -0
  123. package/ios/vendor/CSecp256k1/src/checkmem.h +102 -0
  124. package/ios/vendor/CSecp256k1/src/ecdsa.h +21 -0
  125. package/ios/vendor/CSecp256k1/src/ecdsa_impl.h +304 -0
  126. package/ios/vendor/CSecp256k1/src/eckey.h +25 -0
  127. package/ios/vendor/CSecp256k1/src/eckey_impl.h +92 -0
  128. package/ios/vendor/CSecp256k1/src/ecmult.h +61 -0
  129. package/ios/vendor/CSecp256k1/src/ecmult_const.h +38 -0
  130. package/ios/vendor/CSecp256k1/src/ecmult_const_impl.h +399 -0
  131. package/ios/vendor/CSecp256k1/src/ecmult_gen.h +143 -0
  132. package/ios/vendor/CSecp256k1/src/ecmult_gen_impl.h +341 -0
  133. package/ios/vendor/CSecp256k1/src/ecmult_impl.h +853 -0
  134. package/ios/vendor/CSecp256k1/src/field.h +350 -0
  135. package/ios/vendor/CSecp256k1/src/field_10x26.h +57 -0
  136. package/ios/vendor/CSecp256k1/src/field_10x26_impl.h +1232 -0
  137. package/ios/vendor/CSecp256k1/src/field_5x52.h +62 -0
  138. package/ios/vendor/CSecp256k1/src/field_5x52_impl.h +522 -0
  139. package/ios/vendor/CSecp256k1/src/field_5x52_int128_impl.h +274 -0
  140. package/ios/vendor/CSecp256k1/src/field_impl.h +457 -0
  141. package/ios/vendor/CSecp256k1/src/group.h +212 -0
  142. package/ios/vendor/CSecp256k1/src/group_impl.h +974 -0
  143. package/ios/vendor/CSecp256k1/src/hash.h +44 -0
  144. package/ios/vendor/CSecp256k1/src/hash_impl.h +299 -0
  145. package/ios/vendor/CSecp256k1/src/hsort.h +33 -0
  146. package/ios/vendor/CSecp256k1/src/hsort_impl.h +125 -0
  147. package/ios/vendor/CSecp256k1/src/int128.h +90 -0
  148. package/ios/vendor/CSecp256k1/src/int128_impl.h +18 -0
  149. package/ios/vendor/CSecp256k1/src/int128_native.h +19 -0
  150. package/ios/vendor/CSecp256k1/src/int128_native_impl.h +94 -0
  151. package/ios/vendor/CSecp256k1/src/int128_struct.h +14 -0
  152. package/ios/vendor/CSecp256k1/src/int128_struct_impl.h +205 -0
  153. package/ios/vendor/CSecp256k1/src/modinv32.h +43 -0
  154. package/ios/vendor/CSecp256k1/src/modinv32_impl.h +725 -0
  155. package/ios/vendor/CSecp256k1/src/modinv64.h +47 -0
  156. package/ios/vendor/CSecp256k1/src/modinv64_impl.h +780 -0
  157. package/ios/vendor/CSecp256k1/src/modules/recovery/main_impl.h +159 -0
  158. package/ios/vendor/CSecp256k1/src/precomputed_ecmult.c +16456 -0
  159. package/ios/vendor/CSecp256k1/src/precomputed_ecmult.h +38 -0
  160. package/ios/vendor/CSecp256k1/src/precomputed_ecmult_gen.c +1779 -0
  161. package/ios/vendor/CSecp256k1/src/precomputed_ecmult_gen.h +26 -0
  162. package/ios/vendor/CSecp256k1/src/scalar.h +105 -0
  163. package/ios/vendor/CSecp256k1/src/scalar_4x64.h +19 -0
  164. package/ios/vendor/CSecp256k1/src/scalar_4x64_impl.h +1000 -0
  165. package/ios/vendor/CSecp256k1/src/scalar_8x32.h +19 -0
  166. package/ios/vendor/CSecp256k1/src/scalar_8x32_impl.h +816 -0
  167. package/ios/vendor/CSecp256k1/src/scalar_impl.h +321 -0
  168. package/ios/vendor/CSecp256k1/src/scalar_low.h +24 -0
  169. package/ios/vendor/CSecp256k1/src/scalar_low_impl.h +206 -0
  170. package/ios/vendor/CSecp256k1/src/scratch.h +44 -0
  171. package/ios/vendor/CSecp256k1/src/scratch_impl.h +99 -0
  172. package/ios/vendor/CSecp256k1/src/secp256k1.c +831 -0
  173. package/ios/vendor/CSecp256k1/src/selftest.h +32 -0
  174. package/ios/vendor/CSecp256k1/src/util.h +451 -0
  175. package/ios/vendor/GENERATED.md +4 -0
  176. package/package.json +66 -3
  177. package/src/authonContext.ts +30 -0
  178. package/src/client.ts +459 -0
  179. package/src/errors.ts +58 -0
  180. package/src/index.ts +26 -0
  181. package/src/native.ts +52 -0
  182. package/src/types.ts +171 -0
  183. package/src/useAuthonWallet.ts +103 -0
@@ -0,0 +1,176 @@
1
+ // GENERATED by scripts/sync-native-wallet.mjs from kotlin/authon/src/main/kotlin/dev/authon/sdk/wallet/Eip712.kt. Do not edit: change the source and run the script.
2
+ package dev.authon.sdk.wallet
3
+
4
+ import kotlinx.serialization.json.JsonArray
5
+ import kotlinx.serialization.json.JsonElement
6
+ import kotlinx.serialization.json.JsonObject
7
+ import kotlinx.serialization.json.JsonPrimitive
8
+ import kotlinx.serialization.json.booleanOrNull
9
+ import kotlinx.serialization.json.contentOrNull
10
+ import org.web3j.crypto.Hash
11
+ import org.web3j.crypto.Keys
12
+ import java.math.BigInteger
13
+
14
+ /**
15
+ * EIP-712 v4 hashing with viem's rules (hashTypedData): the EIP712Domain type is derived from the
16
+ * domain fields present unless the request supplies one, dependencies are sorted, arrays hash the
17
+ * concatenated element encodings, and signed integers are 256-bit two's complement. Keccak comes
18
+ * from web3j; only the encoding is assembled here.
19
+ */
20
+ internal object Eip712 {
21
+ data class Field(val name: String, val type: String)
22
+
23
+ private val INT_TYPE = Regex("^(u?)int([0-9]*)$")
24
+ private val BYTES_N = Regex("^bytes([0-9]+)$")
25
+ private val ADDRESS = Regex("^0x[0-9a-fA-F]{40}$")
26
+ private val TWO_256: BigInteger = BigInteger.ONE.shiftLeft(256)
27
+
28
+ fun hashTypedData(typedData: JsonObject): ByteArray {
29
+ val domain = typedData["domain"] as? JsonObject ?: JsonObject(emptyMap())
30
+ val primaryType = (typedData["primaryType"] as? JsonPrimitive)?.contentOrNull
31
+ ?: throw invalid("primaryType missing")
32
+ val provided = parseTypes(typedData["types"] as? JsonObject ?: throw invalid("types missing"))
33
+ val types = LinkedHashMap<String, List<Field>>()
34
+ types["EIP712Domain"] = domainFields(domain)
35
+ types.putAll(provided)
36
+ val parts = mutableListOf(byteArrayOf(0x19, 0x01), hashStruct("EIP712Domain", domain, types))
37
+ if (primaryType != "EIP712Domain") {
38
+ val message = typedData["message"] as? JsonObject ?: throw invalid("message missing")
39
+ parts += hashStruct(primaryType, message, types)
40
+ }
41
+ return Hash.sha3(Bytes.concat(*parts.toTypedArray()))
42
+ }
43
+
44
+ fun parseTypes(obj: JsonObject): Map<String, List<Field>> = obj.mapValues { (name, fields) ->
45
+ (fields as? JsonArray ?: throw invalid("type $name must be an array")).map { f ->
46
+ val o = f as? JsonObject ?: throw invalid("field of $name must be an object")
47
+ Field(
48
+ (o["name"] as? JsonPrimitive)?.contentOrNull ?: throw invalid("field name missing in $name"),
49
+ (o["type"] as? JsonPrimitive)?.contentOrNull ?: throw invalid("field type missing in $name"),
50
+ )
51
+ }
52
+ }
53
+
54
+ /** viem getTypesForEIP712Domain. */
55
+ private fun domainFields(domain: JsonObject): List<Field> = buildList {
56
+ val name = domain["name"] as? JsonPrimitive
57
+ if (name != null && name.isString) add(Field("name", "string"))
58
+ val version = domain["version"] as? JsonPrimitive
59
+ if (version != null && truthy(version)) add(Field("version", "string"))
60
+ val chainId = domain["chainId"] as? JsonPrimitive
61
+ if (chainId != null && !chainId.isString && chainId.booleanOrNull == null && chainId.contentOrNull != null) {
62
+ add(Field("chainId", "uint256"))
63
+ }
64
+ val vc = domain["verifyingContract"] as? JsonPrimitive
65
+ if (vc != null && truthy(vc)) add(Field("verifyingContract", "address"))
66
+ val salt = domain["salt"] as? JsonPrimitive
67
+ if (salt != null && truthy(salt)) add(Field("salt", "bytes32"))
68
+ }
69
+
70
+ private fun truthy(p: JsonPrimitive): Boolean {
71
+ val c = p.contentOrNull ?: return false
72
+ if (p.isString) return c.isNotEmpty()
73
+ p.booleanOrNull?.let { return it }
74
+ return c.toBigDecimalOrNull()?.signum() != 0
75
+ }
76
+
77
+ fun encodeType(primaryType: String, types: Map<String, List<Field>>): String {
78
+ val deps = LinkedHashSet<String>()
79
+ findDependencies(primaryType, types, deps)
80
+ val ordered = listOf(primaryType) + deps.filter { it != primaryType }.sorted()
81
+ return ordered.joinToString("") { t ->
82
+ "$t(" + types.getValue(t).joinToString(",") { "${it.type} ${it.name}" } + ")"
83
+ }
84
+ }
85
+
86
+ private fun findDependencies(type: String, types: Map<String, List<Field>>, out: MutableSet<String>) {
87
+ val base = Regex("^\\w*").find(type)?.value ?: ""
88
+ if (base in out || types[base] == null) return
89
+ out += base
90
+ for (f in types.getValue(base)) findDependencies(f.type, types, out)
91
+ }
92
+
93
+ fun hashStruct(type: String, data: JsonObject, types: Map<String, List<Field>>): ByteArray {
94
+ val fields = types[type] ?: throw invalid("unknown type $type")
95
+ val parts = ArrayList<ByteArray>(fields.size + 1)
96
+ parts += Hash.sha3(Bytes.utf8(encodeType(type, types)))
97
+ for (f in fields) parts += encodeField(f.type, data[f.name], types)
98
+ return Hash.sha3(Bytes.concat(*parts.toTypedArray()))
99
+ }
100
+
101
+ private fun encodeField(type: String, value: JsonElement?, types: Map<String, List<Field>>): ByteArray {
102
+ if (types[type] != null) {
103
+ val obj = value as? JsonObject ?: throw invalid("$type value must be an object")
104
+ return hashStruct(type, obj, types)
105
+ }
106
+ if (type.endsWith("]")) {
107
+ val open = type.lastIndexOf('[')
108
+ val inner = type.substring(0, open)
109
+ val len = type.substring(open + 1, type.length - 1)
110
+ val arr = value as? JsonArray ?: throw invalid("$type value must be an array")
111
+ if (len.isNotEmpty() && len.toIntOrNull() != arr.size) throw invalid("$type expects $len elements")
112
+ return Hash.sha3(Bytes.concat(*arr.map { encodeField(inner, it, types) }.toTypedArray()))
113
+ }
114
+ val p = value as? JsonPrimitive ?: throw invalid("missing value for $type")
115
+ return when {
116
+ type == "string" -> {
117
+ if (!p.isString) throw invalid("string value expected")
118
+ Hash.sha3(Bytes.utf8(p.content))
119
+ }
120
+ type == "bytes" -> {
121
+ if (!p.isString) throw invalid("hex value expected")
122
+ Hash.sha3(Bytes.fromHexOrNull(p.content)?.takeIf { p.content.startsWith("0x") } ?: throw invalid("bytes must be 0x hex"))
123
+ }
124
+ type == "bool" -> {
125
+ val b = if (p.isString) null else p.booleanOrNull
126
+ word(if (b ?: throw invalid("boolean value expected")) BigInteger.ONE else BigInteger.ZERO)
127
+ }
128
+ type == "address" -> {
129
+ val a = p.contentOrNull?.takeIf { p.isString } ?: throw invalid("address expected")
130
+ word(BigInteger(1, Bytes.fromHex(checkAddress(a))))
131
+ }
132
+ INT_TYPE.matches(type) -> {
133
+ val m = INT_TYPE.find(type)!!
134
+ val signed = m.groupValues[1].isEmpty()
135
+ val bits = m.groupValues[2].ifEmpty { "256" }.toInt()
136
+ if (bits < 8 || bits > 256 || bits % 8 != 0) throw invalid("invalid integer type $type")
137
+ val v = JsValues.toBigIntOrNull(p) ?: throw invalid("integer value expected for $type")
138
+ val (min, max) = if (signed) {
139
+ BigInteger.ONE.shiftLeft(bits - 1).negate() to BigInteger.ONE.shiftLeft(bits - 1).subtract(BigInteger.ONE)
140
+ } else {
141
+ BigInteger.ZERO to BigInteger.ONE.shiftLeft(bits).subtract(BigInteger.ONE)
142
+ }
143
+ if (v < min || v > max) throw invalid("$type value out of range")
144
+ word(if (v.signum() < 0) v.add(TWO_256) else v)
145
+ }
146
+ BYTES_N.matches(type) -> {
147
+ val n = BYTES_N.find(type)!!.groupValues[1].toInt()
148
+ if (n < 1 || n > 32) throw invalid("invalid type $type")
149
+ val bytes = p.contentOrNull?.takeIf { p.isString && it.startsWith("0x") }?.let { Bytes.fromHexOrNull(it) }
150
+ ?: throw invalid("$type must be 0x hex")
151
+ if (bytes.size != n) throw invalid("$type expects $n bytes")
152
+ bytes.copyOf(32)
153
+ }
154
+ else -> throw invalid("unsupported type $type")
155
+ }
156
+ }
157
+
158
+ /** viem isAddress (strict): mixed-case addresses must carry a valid EIP-55 checksum. */
159
+ fun checkAddress(address: String): String {
160
+ if (!ADDRESS.matches(address)) throw invalid("invalid address $address")
161
+ val body = address.substring(2)
162
+ val mixed = body.any { it.isUpperCase() } && body.any { it.isLowerCase() }
163
+ if (mixed && Keys.toChecksumAddress(address) != address) throw invalid("address checksum mismatch $address")
164
+ return address
165
+ }
166
+
167
+ private fun word(v: BigInteger): ByteArray {
168
+ val raw = v.toByteArray()
169
+ val out = ByteArray(32)
170
+ val src = if (raw.size > 32) raw.copyOfRange(raw.size - 32, raw.size) else raw
171
+ src.copyInto(out, 32 - src.size)
172
+ return out
173
+ }
174
+
175
+ private fun invalid(message: String) = walletError(WalletErrorCode.INVALID_REQUEST, message)
176
+ }
@@ -0,0 +1,133 @@
1
+ // GENERATED by scripts/sync-native-wallet.mjs from kotlin/authon/src/main/kotlin/dev/authon/sdk/wallet/Encodings.kt. Do not edit: change the source and run the script.
2
+ package dev.authon.sdk.wallet
3
+
4
+ import java.math.BigInteger
5
+
6
+ /** Base58 (Bitcoin and XRP alphabets) and Base58Check with a double-SHA-256 checksum. */
7
+ internal object Base58 {
8
+ const val BITCOIN = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
9
+ const val XRP = "rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz"
10
+ private val FIFTY_EIGHT = BigInteger.valueOf(58)
11
+
12
+ fun encode(data: ByteArray, alphabet: String = BITCOIN): String {
13
+ var n = BigInteger(1, data)
14
+ val out = StringBuilder()
15
+ while (n.signum() > 0) {
16
+ val (q, r) = n.divideAndRemainder(FIFTY_EIGHT)
17
+ out.append(alphabet[r.toInt()])
18
+ n = q
19
+ }
20
+ for (b in data) {
21
+ if (b.toInt() != 0) break
22
+ out.append(alphabet[0])
23
+ }
24
+ return out.reverse().toString()
25
+ }
26
+
27
+ fun decode(text: String, alphabet: String = BITCOIN): ByteArray {
28
+ var n = BigInteger.ZERO
29
+ for (c in text) {
30
+ val digit = alphabet.indexOf(c)
31
+ if (digit < 0) throw walletError(WalletErrorCode.INVALID_REQUEST, "invalid base58")
32
+ n = n.multiply(FIFTY_EIGHT).add(BigInteger.valueOf(digit.toLong()))
33
+ }
34
+ val body = n.toByteArray().let { if (it.size > 1 && it[0].toInt() == 0) it.copyOfRange(1, it.size) else it }
35
+ val zeros = text.takeWhile { it == alphabet[0] }.length
36
+ return ByteArray(zeros) + if (n.signum() == 0) ByteArray(0) else body
37
+ }
38
+
39
+ fun encodeCheck(payload: ByteArray, alphabet: String = BITCOIN): String {
40
+ val checksum = Bytes.sha256(Bytes.sha256(payload)).copyOf(4)
41
+ return encode(payload + checksum, alphabet)
42
+ }
43
+ }
44
+
45
+ /** Bech32 (BIP173) and Bech32m (BIP350) for segwit addresses. */
46
+ internal object Bech32 {
47
+ private const val BECH32M_CONST = 0x2bc830a3
48
+ private const val CHARSET = "qpzry9x8gf2tvdw0s3jn54khce6mua7l"
49
+ private val GEN = intArrayOf(0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3)
50
+
51
+ private fun polymod(values: IntArray): Int {
52
+ var chk = 1
53
+ for (v in values) {
54
+ val top = chk ushr 25
55
+ chk = ((chk and 0x1ffffff) shl 5) xor v
56
+ for (i in 0 until 5) if ((top ushr i) and 1 == 1) chk = chk xor GEN[i]
57
+ }
58
+ return chk
59
+ }
60
+
61
+ private fun hrpExpand(hrp: String): IntArray =
62
+ IntArray(hrp.length) { hrp[it].code ushr 5 } + intArrayOf(0) + IntArray(hrp.length) { hrp[it].code and 31 }
63
+
64
+ fun encode(hrp: String, data: IntArray, bech32m: Boolean = false): String {
65
+ val values = hrpExpand(hrp) + data + IntArray(6)
66
+ val mod = polymod(values) xor (if (bech32m) BECH32M_CONST else 1)
67
+ val checksum = IntArray(6) { (mod ushr (5 * (5 - it))) and 31 }
68
+ return hrp + "1" + (data + checksum).joinToString("") { CHARSET[it].toString() }
69
+ }
70
+
71
+ /** True when [address] is a valid Bech32 string (checksum and charset); case must not be mixed. */
72
+ fun verify(address: String): Boolean {
73
+ if (address.lowercase() != address && address.uppercase() != address) return false
74
+ val s = address.lowercase()
75
+ val pos = s.lastIndexOf('1')
76
+ if (pos < 1 || pos + 7 > s.length || s.length > 90) return false
77
+ val data = s.substring(pos + 1).map { CHARSET.indexOf(it) }.toIntArray()
78
+ if (data.any { it < 0 }) return false
79
+ return polymod(hrpExpand(s.substring(0, pos)) + data) == 1
80
+ }
81
+
82
+ /** 8-bit bytes to 5-bit groups with padding (BIP173 convertbits). */
83
+ fun toWords(bytes: ByteArray): IntArray {
84
+ val out = ArrayList<Int>()
85
+ var acc = 0
86
+ var bits = 0
87
+ for (b in bytes) {
88
+ acc = (acc shl 8) or (b.toInt() and 0xff)
89
+ bits += 8
90
+ while (bits >= 5) {
91
+ bits -= 5
92
+ out += (acc ushr bits) and 31
93
+ }
94
+ }
95
+ if (bits > 0) out += (acc shl (5 - bits)) and 31
96
+ return out.toIntArray()
97
+ }
98
+
99
+ fun segwitV0(hrp: String, program: ByteArray): String = encode(hrp, intArrayOf(0) + toWords(program))
100
+
101
+ /** Segwit address for witness [version] (v0 bech32, v1+ bech32m). */
102
+ fun segwit(hrp: String, version: Int, program: ByteArray): String = encode(hrp, intArrayOf(version) + toWords(program), version > 0)
103
+
104
+ /** Decodes a segwit address of [hrp] to (version, program); null when it is not one. */
105
+ fun decodeSegwit(hrp: String, address: String): Pair<Int, ByteArray>? {
106
+ if (address.lowercase() != address && address.uppercase() != address) return null
107
+ val s = address.lowercase()
108
+ val pos = s.lastIndexOf('1')
109
+ if (pos < 1 || pos + 7 > s.length || s.length > 90 || s.substring(0, pos) != hrp) return null
110
+ val data = s.substring(pos + 1).map { CHARSET.indexOf(it) }.toIntArray()
111
+ if (data.any { it < 0 }) return null
112
+ val check = polymod(hrpExpand(hrp) + data)
113
+ val words = data.copyOfRange(0, data.size - 6)
114
+ if (words.isEmpty()) return null
115
+ val version = words[0]
116
+ if (version > 16 || check != (if (version == 0) 1 else BECH32M_CONST)) return null
117
+ var acc = 0
118
+ var bits = 0
119
+ val out = ArrayList<Byte>()
120
+ for (w in words.drop(1)) {
121
+ acc = (acc shl 5) or w
122
+ bits += 5
123
+ if (bits >= 8) {
124
+ bits -= 8
125
+ out += ((acc ushr bits) and 0xff).toByte()
126
+ }
127
+ }
128
+ if (bits >= 5 || (acc and ((1 shl bits) - 1)) != 0) return null
129
+ val program = out.toByteArray()
130
+ if (program.size < 2 || program.size > 40 || (version == 0 && program.size != 20 && program.size != 32)) return null
131
+ return version to program
132
+ }
133
+ }
@@ -0,0 +1,45 @@
1
+ // GENERATED by scripts/sync-native-wallet.mjs from kotlin/authon/src/main/kotlin/dev/authon/sdk/wallet/EvmAccount.kt. Do not edit: change the source and run the script.
2
+ package dev.authon.sdk.wallet
3
+
4
+ import kotlinx.serialization.json.JsonObject
5
+ import org.web3j.crypto.ECKeyPair
6
+ import org.web3j.crypto.Hash
7
+ import org.web3j.crypto.Keys
8
+ import org.web3j.crypto.Sign
9
+
10
+ /**
11
+ * secp256k1 account backed by web3j (RFC 6979 deterministic, low-s), producing the same bytes as
12
+ * viem's privateKeyToAccount: signatures are r||s||v with v = 27/28.
13
+ * web3j keeps the key as a BigInteger, which cannot be wiped; the object is short-lived.
14
+ */
15
+ internal class EvmAccount(privateKey: ByteArray) {
16
+ private val keyPair: ECKeyPair = ECKeyPair.create(privateKey)
17
+
18
+ val address: String = Keys.toChecksumAddress(Keys.getAddress(keyPair.publicKey))
19
+
20
+ class Signature(val r: ByteArray, val s: ByteArray, val yParity: Int) {
21
+ fun toHex(): String = "0x" + Bytes.toHex(Bytes.concat(r, s, byteArrayOf((27 + yParity).toByte())))
22
+ }
23
+
24
+ fun signDigest(digest: ByteArray): Signature {
25
+ require(digest.size == 32) { "digest must be 32 bytes" }
26
+ val sig = Sign.signMessage(digest, keyPair, false)
27
+ val v = sig.v[0].toInt() and 0xff
28
+ return Signature(sig.r, sig.s, v - 27)
29
+ }
30
+
31
+ /** personal_sign (EIP-191 version 0x45) over raw bytes. */
32
+ fun signMessage(message: ByteArray): String = signDigest(personalMessageHash(message)).toHex()
33
+
34
+ fun signTypedData(typedData: JsonObject): String = signDigest(Eip712.hashTypedData(typedData)).toHex()
35
+
36
+ fun signTransaction(tx: EvmTransaction): String {
37
+ val sig = signDigest(Hash.sha3(tx.serialize(null)))
38
+ return "0x" + Bytes.toHex(tx.serialize(sig))
39
+ }
40
+
41
+ companion object {
42
+ fun personalMessageHash(message: ByteArray): ByteArray =
43
+ Hash.sha3(Bytes.concat(Bytes.utf8("\u0019Ethereum Signed Message:\n${message.size}"), message))
44
+ }
45
+ }
@@ -0,0 +1,180 @@
1
+ // GENERATED by scripts/sync-native-wallet.mjs from kotlin/authon/src/main/kotlin/dev/authon/sdk/wallet/EvmTransaction.kt. Do not edit: change the source and run the script.
2
+ package dev.authon.sdk.wallet
3
+
4
+ import kotlinx.serialization.json.JsonArray
5
+ import kotlinx.serialization.json.JsonElement
6
+ import kotlinx.serialization.json.JsonNull
7
+ import kotlinx.serialization.json.JsonObject
8
+ import kotlinx.serialization.json.JsonPrimitive
9
+ import kotlinx.serialization.json.contentOrNull
10
+ import org.web3j.rlp.RlpEncoder
11
+ import org.web3j.rlp.RlpList
12
+ import org.web3j.rlp.RlpString
13
+ import org.web3j.rlp.RlpType
14
+ import java.math.BigInteger
15
+
16
+ /**
17
+ * EVM transaction in the frame's input shape (parseTransaction + viem), serialized exactly like
18
+ * viem's serializeTransaction for legacy (EIP-155), EIP-2930 and EIP-1559, including contract
19
+ * creation. RLP comes from web3j.
20
+ */
21
+ internal class EvmTransaction(
22
+ val type: Type,
23
+ val chainId: Long,
24
+ val nonce: Long?,
25
+ val gas: BigInteger?,
26
+ val gasPrice: BigInteger?,
27
+ val maxFeePerGas: BigInteger?,
28
+ val maxPriorityFeePerGas: BigInteger?,
29
+ /** Null for a contract creation. */
30
+ val to: String?,
31
+ val value: BigInteger?,
32
+ val data: ByteArray,
33
+ val accessList: List<AccessListEntry>,
34
+ /** The parsed request as the approval summary sees it. */
35
+ val fields: JsonObject,
36
+ ) {
37
+ enum class Type { LEGACY, EIP2930, EIP1559 }
38
+
39
+ class AccessListEntry(val address: String, val storageKeys: List<ByteArray>)
40
+
41
+ fun serialize(signature: EvmAccount.Signature?): ByteArray {
42
+ val items = ArrayList<RlpType>()
43
+ fun num(v: BigInteger?) = RlpString.create(v ?: BigInteger.ZERO)
44
+ fun numL(v: Long?) = RlpString.create(BigInteger.valueOf(v ?: 0L))
45
+ val toItem = RlpString.create(to?.let { Bytes.fromHex(it) } ?: ByteArray(0))
46
+ val accessItems: RlpType = RlpList(
47
+ accessList.map { e ->
48
+ RlpList(RlpString.create(Bytes.fromHex(e.address)), RlpList(e.storageKeys.map { RlpString.create(it) }))
49
+ },
50
+ )
51
+ when (type) {
52
+ Type.LEGACY -> {
53
+ items += listOf(numL(nonce), num(gasPrice), num(gas), toItem, num(value), RlpString.create(data))
54
+ if (signature != null) {
55
+ val v = if (chainId > 0) {
56
+ BigInteger.valueOf(chainId).multiply(BigInteger.TWO).add(BigInteger.valueOf(35L + signature.yParity))
57
+ } else {
58
+ BigInteger.valueOf(27L + signature.yParity)
59
+ }
60
+ items += listOf(RlpString.create(v), sigInt(signature.r), sigInt(signature.s))
61
+ } else if (chainId > 0) {
62
+ items += listOf(numL(chainId), RlpString.create(ByteArray(0)), RlpString.create(ByteArray(0)))
63
+ }
64
+ return RlpEncoder.encode(RlpList(items))
65
+ }
66
+ Type.EIP2930 -> {
67
+ items += listOf(numL(chainId), numL(nonce), num(gasPrice), num(gas), toItem, num(value), RlpString.create(data), accessItems)
68
+ }
69
+ Type.EIP1559 -> {
70
+ items += listOf(
71
+ numL(chainId), numL(nonce), num(maxPriorityFeePerGas), num(maxFeePerGas), num(gas), toItem, num(value),
72
+ RlpString.create(data), accessItems,
73
+ )
74
+ }
75
+ }
76
+ if (signature != null) {
77
+ items += listOf(RlpString.create(BigInteger.valueOf(signature.yParity.toLong())), sigInt(signature.r), sigInt(signature.s))
78
+ }
79
+ val prefix: Byte = if (type == Type.EIP2930) 0x01 else 0x02
80
+ return byteArrayOf(prefix) + RlpEncoder.encode(RlpList(items))
81
+ }
82
+
83
+ private fun sigInt(bytes: ByteArray) = RlpString.create(BigInteger(1, bytes))
84
+
85
+ companion object {
86
+ private val BIGINT_FIELDS = listOf("value", "gas", "gasPrice", "maxFeePerGas", "maxPriorityFeePerGas", "maxFeePerBlobGas")
87
+ private val NUMBER_FIELDS = listOf("nonce", "chainId")
88
+ private val MAX_UINT256: BigInteger = BigInteger.ONE.shiftLeft(256).subtract(BigInteger.ONE)
89
+
90
+ /** The frame's parseTransaction followed by viem's type inference and assertions. */
91
+ fun parse(input: JsonObject): EvmTransaction {
92
+ val tx = LinkedHashMap<String, JsonElement>(input)
93
+ val big = HashMap<String, BigInteger>()
94
+ for (f in BIGINT_FIELDS + NUMBER_FIELDS) {
95
+ val raw = tx[f] ?: continue
96
+ if (raw is JsonNull) continue
97
+ val v = JsValues.toBigIntOrNull(raw) ?: throw invalid("transaction numeric field invalid")
98
+ big[f] = v
99
+ tx[f] = JsonPrimitive(v)
100
+ }
101
+ val chainIdBig = big["chainId"] ?: throw invalid("chainId required")
102
+ val chainId = chainIdBig.toLong()
103
+ val nonce = big["nonce"]?.toLong()
104
+
105
+ val explicit = (tx["type"] as? JsonPrimitive)?.contentOrNull
106
+ val type = when (explicit) {
107
+ null -> when {
108
+ big["maxFeePerBlobGas"] != null || tx["blobs"].present() || tx["blobVersionedHashes"].present() ->
109
+ throw walletError(WalletErrorCode.UNSUPPORTED_TYPE, "blob transactions are not supported")
110
+ tx["authorizationList"].present() ->
111
+ throw walletError(WalletErrorCode.UNSUPPORTED_TYPE, "EIP-7702 transactions are not supported")
112
+ big["maxFeePerGas"] != null || big["maxPriorityFeePerGas"] != null -> Type.EIP1559
113
+ big["gasPrice"] != null -> if (tx["accessList"].present()) Type.EIP2930 else Type.LEGACY
114
+ else -> throw invalid("cannot infer the transaction type")
115
+ }
116
+ "legacy", "0x0" -> Type.LEGACY
117
+ "eip2930", "0x1" -> Type.EIP2930
118
+ "eip1559", "0x2" -> Type.EIP1559
119
+ else -> throw walletError(WalletErrorCode.UNSUPPORTED_TYPE, "transaction type $explicit is not supported")
120
+ }
121
+
122
+ val toRaw = tx["to"]
123
+ val to = when {
124
+ toRaw == null || toRaw is JsonNull -> null
125
+ toRaw is JsonPrimitive && toRaw.isString && toRaw.content.isEmpty() -> null
126
+ toRaw is JsonPrimitive && toRaw.isString -> Eip712.checkAddress(toRaw.content)
127
+ else -> throw invalid("to must be an address")
128
+ }
129
+ val dataRaw = tx["data"]
130
+ val data = when {
131
+ dataRaw == null || dataRaw is JsonNull -> ByteArray(0)
132
+ dataRaw is JsonPrimitive && dataRaw.isString && dataRaw.content.startsWith("0x") ->
133
+ Bytes.fromHexOrNull(dataRaw.content) ?: throw invalid("data must be hex")
134
+ else -> throw invalid("data must be 0x hex")
135
+ }
136
+ val accessList = parseAccessList(tx["accessList"])
137
+
138
+ val gasPrice = big["gasPrice"]
139
+ val maxFee = big["maxFeePerGas"]
140
+ val maxTip = big["maxPriorityFeePerGas"]
141
+ if (chainId <= 0 && type != Type.LEGACY) throw invalid("invalid chainId")
142
+ if (type == Type.LEGACY && tx["chainId"] != null && chainId <= 0) throw invalid("invalid chainId")
143
+ when (type) {
144
+ Type.LEGACY, Type.EIP2930 -> {
145
+ if (maxFee != null || maxTip != null) throw invalid("maxFeePerGas/maxPriorityFeePerGas are not valid for this type")
146
+ if (gasPrice != null && gasPrice > MAX_UINT256) throw invalid("gasPrice too high")
147
+ }
148
+ Type.EIP1559 -> {
149
+ if (maxFee != null && maxFee > MAX_UINT256) throw invalid("maxFeePerGas too high")
150
+ if (maxTip != null && maxFee != null && maxTip > maxFee) throw invalid("maxPriorityFeePerGas above maxFeePerGas")
151
+ }
152
+ }
153
+ for ((k, v) in big) if (v.signum() < 0) throw invalid("$k must not be negative")
154
+ if (type == Type.LEGACY && accessList.isNotEmpty()) throw invalid("accessList is not valid for legacy transactions")
155
+
156
+ return EvmTransaction(
157
+ type, chainId, nonce, big["gas"], gasPrice, maxFee, maxTip, to, big["value"], data, accessList, JsonObject(tx),
158
+ )
159
+ }
160
+
161
+ private fun parseAccessList(raw: JsonElement?): List<AccessListEntry> {
162
+ if (raw == null || raw is JsonNull) return emptyList()
163
+ val arr = raw as? JsonArray ?: throw invalid("accessList must be an array")
164
+ return arr.map { item ->
165
+ val o = item as? JsonObject ?: throw invalid("accessList entry must be an object")
166
+ val address = (o["address"] as? JsonPrimitive)?.contentOrNull ?: throw invalid("accessList address missing")
167
+ val keys = (o["storageKeys"] as? JsonArray ?: JsonArray(emptyList())).map { k ->
168
+ val hex = (k as? JsonPrimitive)?.contentOrNull ?: throw invalid("storage key must be hex")
169
+ if (hex.length != 66) throw invalid("storage key must be 32 bytes")
170
+ Bytes.fromHexOrNull(hex) ?: throw invalid("storage key must be hex")
171
+ }
172
+ AccessListEntry(Eip712.checkAddress(address), keys)
173
+ }
174
+ }
175
+
176
+ private fun JsonElement?.present(): Boolean = this != null && this !is JsonNull
177
+
178
+ private fun invalid(message: String) = walletError(WalletErrorCode.INVALID_REQUEST, message)
179
+ }
180
+ }
@@ -0,0 +1,44 @@
1
+ // GENERATED by scripts/sync-native-wallet.mjs from kotlin/authon/src/main/kotlin/dev/authon/sdk/wallet/GfTables.kt. Do not edit: change the source and run the script.
2
+ package dev.authon.sdk.wallet
3
+
4
+ // GF(2^8) tables of the shamir-secret-sharing JS library (polynomial x^8+x^4+x^3+x+1, generator 0xe5),
5
+ // copied verbatim so combine/split/deriveShare produce the same bytes as the web frame.
6
+ internal object GfTables {
7
+ val LOG: IntArray = intArrayOf(
8
+ 0x00, 0xff, 0xc8, 0x08, 0x91, 0x10, 0xd0, 0x36, 0x5a, 0x3e, 0xd8, 0x43, 0x99, 0x77, 0xfe, 0x18,
9
+ 0x23, 0x20, 0x07, 0x70, 0xa1, 0x6c, 0x0c, 0x7f, 0x62, 0x8b, 0x40, 0x46, 0xc7, 0x4b, 0xe0, 0x0e,
10
+ 0xeb, 0x16, 0xe8, 0xad, 0xcf, 0xcd, 0x39, 0x53, 0x6a, 0x27, 0x35, 0x93, 0xd4, 0x4e, 0x48, 0xc3,
11
+ 0x2b, 0x79, 0x54, 0x28, 0x09, 0x78, 0x0f, 0x21, 0x90, 0x87, 0x14, 0x2a, 0xa9, 0x9c, 0xd6, 0x74,
12
+ 0xb4, 0x7c, 0xde, 0xed, 0xb1, 0x86, 0x76, 0xa4, 0x98, 0xe2, 0x96, 0x8f, 0x02, 0x32, 0x1c, 0xc1,
13
+ 0x33, 0xee, 0xef, 0x81, 0xfd, 0x30, 0x5c, 0x13, 0x9d, 0x29, 0x17, 0xc4, 0x11, 0x44, 0x8c, 0x80,
14
+ 0xf3, 0x73, 0x42, 0x1e, 0x1d, 0xb5, 0xf0, 0x12, 0xd1, 0x5b, 0x41, 0xa2, 0xd7, 0x2c, 0xe9, 0xd5,
15
+ 0x59, 0xcb, 0x50, 0xa8, 0xdc, 0xfc, 0xf2, 0x56, 0x72, 0xa6, 0x65, 0x2f, 0x9f, 0x9b, 0x3d, 0xba,
16
+ 0x7d, 0xc2, 0x45, 0x82, 0xa7, 0x57, 0xb6, 0xa3, 0x7a, 0x75, 0x4f, 0xae, 0x3f, 0x37, 0x6d, 0x47,
17
+ 0x61, 0xbe, 0xab, 0xd3, 0x5f, 0xb0, 0x58, 0xaf, 0xca, 0x5e, 0xfa, 0x85, 0xe4, 0x4d, 0x8a, 0x05,
18
+ 0xfb, 0x60, 0xb7, 0x7b, 0xb8, 0x26, 0x4a, 0x67, 0xc6, 0x1a, 0xf8, 0x69, 0x25, 0xb3, 0xdb, 0xbd,
19
+ 0x66, 0xdd, 0xf1, 0xd2, 0xdf, 0x03, 0x8d, 0x34, 0xd9, 0x92, 0x0d, 0x63, 0x55, 0xaa, 0x49, 0xec,
20
+ 0xbc, 0x95, 0x3c, 0x84, 0x0b, 0xf5, 0xe6, 0xe7, 0xe5, 0xac, 0x7e, 0x6e, 0xb9, 0xf9, 0xda, 0x8e,
21
+ 0x9a, 0xc9, 0x24, 0xe1, 0x0a, 0x15, 0x6b, 0x3a, 0xa0, 0x51, 0xf4, 0xea, 0xb2, 0x97, 0x9e, 0x5d,
22
+ 0x22, 0x88, 0x94, 0xce, 0x19, 0x01, 0x71, 0x4c, 0xa5, 0xe3, 0xc5, 0x31, 0xbb, 0xcc, 0x1f, 0x2d,
23
+ 0x3b, 0x52, 0x6f, 0xf6, 0x2e, 0x89, 0xf7, 0xc0, 0x68, 0x1b, 0x64, 0x04, 0x06, 0xbf, 0x83, 0x38,
24
+ )
25
+
26
+ val EXP: IntArray = intArrayOf(
27
+ 0x01, 0xe5, 0x4c, 0xb5, 0xfb, 0x9f, 0xfc, 0x12, 0x03, 0x34, 0xd4, 0xc4, 0x16, 0xba, 0x1f, 0x36,
28
+ 0x05, 0x5c, 0x67, 0x57, 0x3a, 0xd5, 0x21, 0x5a, 0x0f, 0xe4, 0xa9, 0xf9, 0x4e, 0x64, 0x63, 0xee,
29
+ 0x11, 0x37, 0xe0, 0x10, 0xd2, 0xac, 0xa5, 0x29, 0x33, 0x59, 0x3b, 0x30, 0x6d, 0xef, 0xf4, 0x7b,
30
+ 0x55, 0xeb, 0x4d, 0x50, 0xb7, 0x2a, 0x07, 0x8d, 0xff, 0x26, 0xd7, 0xf0, 0xc2, 0x7e, 0x09, 0x8c,
31
+ 0x1a, 0x6a, 0x62, 0x0b, 0x5d, 0x82, 0x1b, 0x8f, 0x2e, 0xbe, 0xa6, 0x1d, 0xe7, 0x9d, 0x2d, 0x8a,
32
+ 0x72, 0xd9, 0xf1, 0x27, 0x32, 0xbc, 0x77, 0x85, 0x96, 0x70, 0x08, 0x69, 0x56, 0xdf, 0x99, 0x94,
33
+ 0xa1, 0x90, 0x18, 0xbb, 0xfa, 0x7a, 0xb0, 0xa7, 0xf8, 0xab, 0x28, 0xd6, 0x15, 0x8e, 0xcb, 0xf2,
34
+ 0x13, 0xe6, 0x78, 0x61, 0x3f, 0x89, 0x46, 0x0d, 0x35, 0x31, 0x88, 0xa3, 0x41, 0x80, 0xca, 0x17,
35
+ 0x5f, 0x53, 0x83, 0xfe, 0xc3, 0x9b, 0x45, 0x39, 0xe1, 0xf5, 0x9e, 0x19, 0x5e, 0xb6, 0xcf, 0x4b,
36
+ 0x38, 0x04, 0xb9, 0x2b, 0xe2, 0xc1, 0x4a, 0xdd, 0x48, 0x0c, 0xd0, 0x7d, 0x3d, 0x58, 0xde, 0x7c,
37
+ 0xd8, 0x14, 0x6b, 0x87, 0x47, 0xe8, 0x79, 0x84, 0x73, 0x3c, 0xbd, 0x92, 0xc9, 0x23, 0x8b, 0x97,
38
+ 0x95, 0x44, 0xdc, 0xad, 0x40, 0x65, 0x86, 0xa2, 0xa4, 0xcc, 0x7f, 0xec, 0xc0, 0xaf, 0x91, 0xfd,
39
+ 0xf7, 0x4f, 0x81, 0x2f, 0x5b, 0xea, 0xa8, 0x1c, 0x02, 0xd1, 0x98, 0x71, 0xed, 0x25, 0xe3, 0x24,
40
+ 0x06, 0x68, 0xb3, 0x93, 0x2c, 0x6f, 0x3e, 0x6c, 0x0a, 0xb8, 0xce, 0xae, 0x74, 0xb1, 0x42, 0xb4,
41
+ 0x1e, 0xd3, 0x49, 0xe9, 0x9c, 0xc8, 0xc6, 0xc7, 0x22, 0x6e, 0xdb, 0x20, 0xbf, 0x43, 0x51, 0x52,
42
+ 0x66, 0xb2, 0x76, 0x60, 0xda, 0xc5, 0xf3, 0xf6, 0xaa, 0xcd, 0x9a, 0xa0, 0x75, 0x54, 0x0e, 0x01,
43
+ )
44
+ }