@authon/react-native-wallet 0.0.0-stage → 0.1.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 (159) hide show
  1. package/README.md +221 -2
  2. package/android/build.gradle +40 -0
  3. package/android/consumer-rules.pro +10 -0
  4. package/android/src/main/AndroidManifest.xml +4 -0
  5. package/android/src/main/java/dev/authon/reactnative/wallet/AuthonWalletModule.kt +181 -0
  6. package/android/src/vendor/GENERATED.md +4 -0
  7. package/android/src/vendor/kotlin/dev/authon/sdk/wallet/AuthonWallet.kt +191 -0
  8. package/android/src/vendor/kotlin/dev/authon/sdk/wallet/Bytes.kt +74 -0
  9. package/android/src/vendor/kotlin/dev/authon/sdk/wallet/CredentialManagerPasskeys.kt +192 -0
  10. package/android/src/vendor/kotlin/dev/authon/sdk/wallet/DeviceStore.kt +170 -0
  11. package/android/src/vendor/kotlin/dev/authon/sdk/wallet/DialogWalletApprover.kt +141 -0
  12. package/android/src/vendor/kotlin/dev/authon/sdk/wallet/Eip712.kt +176 -0
  13. package/android/src/vendor/kotlin/dev/authon/sdk/wallet/EvmAccount.kt +45 -0
  14. package/android/src/vendor/kotlin/dev/authon/sdk/wallet/EvmTransaction.kt +180 -0
  15. package/android/src/vendor/kotlin/dev/authon/sdk/wallet/GfTables.kt +44 -0
  16. package/android/src/vendor/kotlin/dev/authon/sdk/wallet/HdWallet.kt +130 -0
  17. package/android/src/vendor/kotlin/dev/authon/sdk/wallet/Http.kt +82 -0
  18. package/android/src/vendor/kotlin/dev/authon/sdk/wallet/JsValues.kt +83 -0
  19. package/android/src/vendor/kotlin/dev/authon/sdk/wallet/KeystoreDeviceStore.kt +232 -0
  20. package/android/src/vendor/kotlin/dev/authon/sdk/wallet/Prf.kt +111 -0
  21. package/android/src/vendor/kotlin/dev/authon/sdk/wallet/Proof.kt +134 -0
  22. package/android/src/vendor/kotlin/dev/authon/sdk/wallet/Shamir.kt +106 -0
  23. package/android/src/vendor/kotlin/dev/authon/sdk/wallet/SignSummary.kt +335 -0
  24. package/android/src/vendor/kotlin/dev/authon/sdk/wallet/WalletApi.kt +353 -0
  25. package/android/src/vendor/kotlin/dev/authon/sdk/wallet/WalletError.kt +58 -0
  26. package/android/src/vendor/kotlin/dev/authon/sdk/wallet/WalletOps.kt +449 -0
  27. package/android/src/vendor/kotlin/dev/authon/sdk/wallet/WalletTypes.kt +71 -0
  28. package/build/authonContext.d.ts +19 -0
  29. package/build/authonContext.d.ts.map +1 -0
  30. package/build/authonContext.js +20 -0
  31. package/build/authonContext.js.map +1 -0
  32. package/build/client.d.ts +76 -0
  33. package/build/client.d.ts.map +1 -0
  34. package/build/client.js +349 -0
  35. package/build/client.js.map +1 -0
  36. package/build/errors.d.ts +18 -0
  37. package/build/errors.d.ts.map +1 -0
  38. package/build/errors.js +9 -0
  39. package/build/errors.js.map +1 -0
  40. package/build/index.d.ts +7 -0
  41. package/build/index.d.ts.map +1 -0
  42. package/build/index.js +4 -0
  43. package/build/index.js.map +1 -0
  44. package/build/native.d.ts +39 -0
  45. package/build/native.d.ts.map +1 -0
  46. package/build/native.js +12 -0
  47. package/build/native.js.map +1 -0
  48. package/build/types.d.ts +121 -0
  49. package/build/types.d.ts.map +1 -0
  50. package/build/types.js +3 -0
  51. package/build/types.js.map +1 -0
  52. package/build/useAuthonWallet.d.ts +25 -0
  53. package/build/useAuthonWallet.d.ts.map +1 -0
  54. package/build/useAuthonWallet.js +77 -0
  55. package/build/useAuthonWallet.js.map +1 -0
  56. package/expo-module.config.json +9 -0
  57. package/ios/AuthonReactNativeWallet.podspec +37 -0
  58. package/ios/AuthonWalletModule.swift +190 -0
  59. package/ios/vendor/AuthonWallet/AuthonWallet.swift +212 -0
  60. package/ios/vendor/AuthonWallet/Crypto/BIP39Wordlist.swift +262 -0
  61. package/ios/vendor/AuthonWallet/Crypto/HDKey.swift +108 -0
  62. package/ios/vendor/AuthonWallet/Crypto/Secp256k1.swift +104 -0
  63. package/ios/vendor/AuthonWallet/Crypto/Shamir.swift +123 -0
  64. package/ios/vendor/AuthonWallet/EVM/Address.swift +57 -0
  65. package/ios/vendor/AuthonWallet/EVM/EvmAccount.swift +48 -0
  66. package/ios/vendor/AuthonWallet/EVM/Transaction.swift +165 -0
  67. package/ios/vendor/AuthonWallet/EVM/TypedData.swift +193 -0
  68. package/ios/vendor/AuthonWallet/Support/BigInteger.swift +220 -0
  69. package/ios/vendor/AuthonWallet/Support/Bytes.swift +89 -0
  70. package/ios/vendor/AuthonWallet/Support/JSONValue.swift +341 -0
  71. package/ios/vendor/AuthonWallet/UI/WalletApprover.swift +250 -0
  72. package/ios/vendor/AuthonWallet/Wallet/Backup.swift +69 -0
  73. package/ios/vendor/AuthonWallet/Wallet/DeviceStore.swift +351 -0
  74. package/ios/vendor/AuthonWallet/Wallet/Passkeys.swift +190 -0
  75. package/ios/vendor/AuthonWallet/Wallet/Proof.swift +143 -0
  76. package/ios/vendor/AuthonWallet/Wallet/Shares.swift +116 -0
  77. package/ios/vendor/AuthonWallet/Wallet/Summary.swift +342 -0
  78. package/ios/vendor/AuthonWallet/Wallet/WalletAPI.swift +350 -0
  79. package/ios/vendor/AuthonWallet/Wallet/WalletOps.swift +555 -0
  80. package/ios/vendor/AuthonWallet/WalletError.swift +54 -0
  81. package/ios/vendor/CKeccak/LICENSE +22 -0
  82. package/ios/vendor/CKeccak/README.md +27 -0
  83. package/ios/vendor/CKeccak/byte_order.h +59 -0
  84. package/ios/vendor/CKeccak/include/ckeccak.h +9 -0
  85. package/ios/vendor/CKeccak/memzero.c +75 -0
  86. package/ios/vendor/CKeccak/memzero.h +8 -0
  87. package/ios/vendor/CKeccak/options.h +99 -0
  88. package/ios/vendor/CKeccak/sha3.c +413 -0
  89. package/ios/vendor/CKeccak/sha3.h +89 -0
  90. package/ios/vendor/CSecp256k1/COPYING +19 -0
  91. package/ios/vendor/CSecp256k1/README.md +35 -0
  92. package/ios/vendor/CSecp256k1/build/precomputed_ecmult.c +3 -0
  93. package/ios/vendor/CSecp256k1/build/precomputed_ecmult_gen.c +3 -0
  94. package/ios/vendor/CSecp256k1/build/secp256k1.c +3 -0
  95. package/ios/vendor/CSecp256k1/include/secp256k1.h +899 -0
  96. package/ios/vendor/CSecp256k1/include/secp256k1_preallocated.h +134 -0
  97. package/ios/vendor/CSecp256k1/include/secp256k1_recovery.h +113 -0
  98. package/ios/vendor/CSecp256k1/src/assumptions.h +87 -0
  99. package/ios/vendor/CSecp256k1/src/checkmem.h +102 -0
  100. package/ios/vendor/CSecp256k1/src/ecdsa.h +21 -0
  101. package/ios/vendor/CSecp256k1/src/ecdsa_impl.h +304 -0
  102. package/ios/vendor/CSecp256k1/src/eckey.h +25 -0
  103. package/ios/vendor/CSecp256k1/src/eckey_impl.h +92 -0
  104. package/ios/vendor/CSecp256k1/src/ecmult.h +61 -0
  105. package/ios/vendor/CSecp256k1/src/ecmult_const.h +38 -0
  106. package/ios/vendor/CSecp256k1/src/ecmult_const_impl.h +399 -0
  107. package/ios/vendor/CSecp256k1/src/ecmult_gen.h +143 -0
  108. package/ios/vendor/CSecp256k1/src/ecmult_gen_impl.h +341 -0
  109. package/ios/vendor/CSecp256k1/src/ecmult_impl.h +853 -0
  110. package/ios/vendor/CSecp256k1/src/field.h +350 -0
  111. package/ios/vendor/CSecp256k1/src/field_10x26.h +57 -0
  112. package/ios/vendor/CSecp256k1/src/field_10x26_impl.h +1232 -0
  113. package/ios/vendor/CSecp256k1/src/field_5x52.h +62 -0
  114. package/ios/vendor/CSecp256k1/src/field_5x52_impl.h +522 -0
  115. package/ios/vendor/CSecp256k1/src/field_5x52_int128_impl.h +274 -0
  116. package/ios/vendor/CSecp256k1/src/field_impl.h +457 -0
  117. package/ios/vendor/CSecp256k1/src/group.h +212 -0
  118. package/ios/vendor/CSecp256k1/src/group_impl.h +974 -0
  119. package/ios/vendor/CSecp256k1/src/hash.h +44 -0
  120. package/ios/vendor/CSecp256k1/src/hash_impl.h +299 -0
  121. package/ios/vendor/CSecp256k1/src/hsort.h +33 -0
  122. package/ios/vendor/CSecp256k1/src/hsort_impl.h +125 -0
  123. package/ios/vendor/CSecp256k1/src/int128.h +90 -0
  124. package/ios/vendor/CSecp256k1/src/int128_impl.h +18 -0
  125. package/ios/vendor/CSecp256k1/src/int128_native.h +19 -0
  126. package/ios/vendor/CSecp256k1/src/int128_native_impl.h +94 -0
  127. package/ios/vendor/CSecp256k1/src/int128_struct.h +14 -0
  128. package/ios/vendor/CSecp256k1/src/int128_struct_impl.h +205 -0
  129. package/ios/vendor/CSecp256k1/src/modinv32.h +43 -0
  130. package/ios/vendor/CSecp256k1/src/modinv32_impl.h +725 -0
  131. package/ios/vendor/CSecp256k1/src/modinv64.h +47 -0
  132. package/ios/vendor/CSecp256k1/src/modinv64_impl.h +780 -0
  133. package/ios/vendor/CSecp256k1/src/modules/recovery/main_impl.h +159 -0
  134. package/ios/vendor/CSecp256k1/src/precomputed_ecmult.c +16456 -0
  135. package/ios/vendor/CSecp256k1/src/precomputed_ecmult.h +38 -0
  136. package/ios/vendor/CSecp256k1/src/precomputed_ecmult_gen.c +1779 -0
  137. package/ios/vendor/CSecp256k1/src/precomputed_ecmult_gen.h +26 -0
  138. package/ios/vendor/CSecp256k1/src/scalar.h +105 -0
  139. package/ios/vendor/CSecp256k1/src/scalar_4x64.h +19 -0
  140. package/ios/vendor/CSecp256k1/src/scalar_4x64_impl.h +1000 -0
  141. package/ios/vendor/CSecp256k1/src/scalar_8x32.h +19 -0
  142. package/ios/vendor/CSecp256k1/src/scalar_8x32_impl.h +816 -0
  143. package/ios/vendor/CSecp256k1/src/scalar_impl.h +321 -0
  144. package/ios/vendor/CSecp256k1/src/scalar_low.h +24 -0
  145. package/ios/vendor/CSecp256k1/src/scalar_low_impl.h +206 -0
  146. package/ios/vendor/CSecp256k1/src/scratch.h +44 -0
  147. package/ios/vendor/CSecp256k1/src/scratch_impl.h +99 -0
  148. package/ios/vendor/CSecp256k1/src/secp256k1.c +831 -0
  149. package/ios/vendor/CSecp256k1/src/selftest.h +32 -0
  150. package/ios/vendor/CSecp256k1/src/util.h +451 -0
  151. package/ios/vendor/GENERATED.md +4 -0
  152. package/package.json +65 -3
  153. package/src/authonContext.ts +30 -0
  154. package/src/client.ts +375 -0
  155. package/src/errors.ts +52 -0
  156. package/src/index.ts +21 -0
  157. package/src/native.ts +50 -0
  158. package/src/types.ts +120 -0
  159. package/src/useAuthonWallet.ts +103 -0
@@ -0,0 +1,341 @@
1
+ /***********************************************************************
2
+ * Copyright (c) Pieter Wuille, Gregory Maxwell, Peter Dettman *
3
+ * Distributed under the MIT software license, see the accompanying *
4
+ * file COPYING or https://www.opensource.org/licenses/mit-license.php.*
5
+ ***********************************************************************/
6
+
7
+ #ifndef SECP256K1_ECMULT_GEN_IMPL_H
8
+ #define SECP256K1_ECMULT_GEN_IMPL_H
9
+
10
+ #include "util.h"
11
+ #include "scalar.h"
12
+ #include "group.h"
13
+ #include "ecmult_gen.h"
14
+ #include "hash_impl.h"
15
+ #include "precomputed_ecmult_gen.h"
16
+
17
+ static void secp256k1_ecmult_gen_context_build(secp256k1_ecmult_gen_context *ctx) {
18
+ secp256k1_ecmult_gen_blind(ctx, NULL);
19
+ ctx->built = 1;
20
+ }
21
+
22
+ static int secp256k1_ecmult_gen_context_is_built(const secp256k1_ecmult_gen_context* ctx) {
23
+ return ctx->built;
24
+ }
25
+
26
+ static void secp256k1_ecmult_gen_context_clear(secp256k1_ecmult_gen_context *ctx) {
27
+ ctx->built = 0;
28
+ secp256k1_scalar_clear(&ctx->scalar_offset);
29
+ secp256k1_ge_clear(&ctx->ge_offset);
30
+ secp256k1_fe_clear(&ctx->proj_blind);
31
+ }
32
+
33
+ /* Compute the scalar (2^COMB_BITS - 1) / 2, the difference between the gn argument to
34
+ * secp256k1_ecmult_gen, and the scalar whose encoding the table lookup bits are drawn
35
+ * from (before applying blinding). */
36
+ static void secp256k1_ecmult_gen_scalar_diff(secp256k1_scalar* diff) {
37
+ int i;
38
+
39
+ /* Compute scalar -1/2. */
40
+ secp256k1_scalar neghalf;
41
+ secp256k1_scalar_half(&neghalf, &secp256k1_scalar_one);
42
+ secp256k1_scalar_negate(&neghalf, &neghalf);
43
+
44
+ /* Compute offset = 2^(COMB_BITS - 1). */
45
+ *diff = secp256k1_scalar_one;
46
+ for (i = 0; i < COMB_BITS - 1; ++i) {
47
+ secp256k1_scalar_add(diff, diff, diff);
48
+ }
49
+
50
+ /* The result is the sum 2^(COMB_BITS - 1) + (-1/2). */
51
+ secp256k1_scalar_add(diff, diff, &neghalf);
52
+ }
53
+
54
+ static void secp256k1_ecmult_gen(const secp256k1_ecmult_gen_context *ctx, secp256k1_gej *r, const secp256k1_scalar *gn) {
55
+ uint32_t comb_off;
56
+ secp256k1_ge add;
57
+ secp256k1_fe neg;
58
+ secp256k1_ge_storage adds;
59
+ secp256k1_scalar d;
60
+ /* Array of uint32_t values large enough to store COMB_BITS bits. Only the bottom
61
+ * 8 are ever nonzero, but having the zero padding at the end if COMB_BITS>256
62
+ * avoids the need to deal with out-of-bounds reads from a scalar. */
63
+ uint32_t recoded[(COMB_BITS + 31) >> 5] = {0};
64
+ int first = 1, i;
65
+
66
+ memset(&adds, 0, sizeof(adds));
67
+
68
+ /* We want to compute R = gn*G.
69
+ *
70
+ * To blind the scalar used in the computation, we rewrite this to be
71
+ * R = (gn - b)*G + b*G, with a blinding value b determined by the context.
72
+ *
73
+ * The multiplication (gn-b)*G will be performed using a signed-digit multi-comb (see Section
74
+ * 3.3 of "Fast and compact elliptic-curve cryptography" by Mike Hamburg,
75
+ * https://eprint.iacr.org/2012/309).
76
+ *
77
+ * Let comb(s, P) = sum((2*s[i]-1)*2^i*P for i=0..COMB_BITS-1), where s[i] is the i'th bit of
78
+ * the binary representation of scalar s. So the s[i] values determine whether -2^i*P (s[i]=0)
79
+ * or +2^i*P (s[i]=1) are added together. COMB_BITS is at least 256, so all bits of s are
80
+ * covered. By manipulating:
81
+ *
82
+ * comb(s, P) = sum((2*s[i]-1)*2^i*P for i=0..COMB_BITS-1)
83
+ * <=> comb(s, P) = sum((2*s[i]-1)*2^i for i=0..COMB_BITS-1) * P
84
+ * <=> comb(s, P) = (2*sum(s[i]*2^i for i=0..COMB_BITS-1) - sum(2^i for i=0..COMB_BITS-1)) * P
85
+ * <=> comb(s, P) = (2*s - (2^COMB_BITS - 1)) * P
86
+ *
87
+ * If we wanted to compute (gn-b)*G as comb(s, G), it would need to hold that
88
+ *
89
+ * (gn - b) * G = (2*s - (2^COMB_BITS - 1)) * G
90
+ * <=> s = (gn - b + (2^COMB_BITS - 1))/2 (mod order)
91
+ *
92
+ * We use an alternative here that avoids the modular division by two: instead we compute
93
+ * (gn-b)*G as comb(d, G/2). For that to hold it must be the case that
94
+ *
95
+ * (gn - b) * G = (2*d - (2^COMB_BITS - 1)) * (G/2)
96
+ * <=> d = gn - b + (2^COMB_BITS - 1)/2 (mod order)
97
+ *
98
+ * Adding precomputation, our final equations become:
99
+ *
100
+ * ctx->scalar_offset = (2^COMB_BITS - 1)/2 - b (mod order)
101
+ * ctx->ge_offset = b*G
102
+ * d = gn + ctx->scalar_offset (mod order)
103
+ * R = comb(d, G/2) + ctx->ge_offset
104
+ *
105
+ * comb(d, G/2) function is then computed by summing + or - 2^(i-1)*G, for i=0..COMB_BITS-1,
106
+ * depending on the value of the bits d[i] of the binary representation of scalar d.
107
+ */
108
+
109
+ /* Compute the scalar d = (gn + ctx->scalar_offset). */
110
+ secp256k1_scalar_add(&d, &ctx->scalar_offset, gn);
111
+ /* Convert to recoded array. */
112
+ for (i = 0; i < 8 && i < ((COMB_BITS + 31) >> 5); ++i) {
113
+ recoded[i] = secp256k1_scalar_get_bits_limb32(&d, 32 * i, 32);
114
+ }
115
+ secp256k1_scalar_clear(&d);
116
+
117
+ /* In secp256k1_ecmult_gen_prec_table we have precomputed sums of the
118
+ * (2*d[i]-1) * 2^(i-1) * G points, for various combinations of i positions.
119
+ * We rewrite our equation in terms of these table entries.
120
+ *
121
+ * Let mask(b) = sum(2^((b*COMB_TEETH + t)*COMB_SPACING) for t=0..COMB_TEETH-1),
122
+ * with b ranging from 0 to COMB_BLOCKS-1. So for example with COMB_BLOCKS=11,
123
+ * COMB_TEETH=6, COMB_SPACING=4, we would have:
124
+ * mask(0) = 2^0 + 2^4 + 2^8 + 2^12 + 2^16 + 2^20,
125
+ * mask(1) = 2^24 + 2^28 + 2^32 + 2^36 + 2^40 + 2^44,
126
+ * mask(2) = 2^48 + 2^52 + 2^56 + 2^60 + 2^64 + 2^68,
127
+ * ...
128
+ * mask(10) = 2^240 + 2^244 + 2^248 + 2^252 + 2^256 + 2^260
129
+ *
130
+ * We will split up the bits d[i] using these masks. Specifically, each mask is
131
+ * used COMB_SPACING times, with different shifts:
132
+ *
133
+ * d = (d & mask(0)<<0) + (d & mask(1)<<0) + ... + (d & mask(COMB_BLOCKS-1)<<0) +
134
+ * (d & mask(0)<<1) + (d & mask(1)<<1) + ... + (d & mask(COMB_BLOCKS-1)<<1) +
135
+ * ...
136
+ * (d & mask(0)<<(COMB_SPACING-1)) + ...
137
+ *
138
+ * Now define table(b, m) = (m - mask(b)/2) * G, and we will precompute these values for
139
+ * b=0..COMB_BLOCKS-1, and for all values m which (d & mask(b)) can take (so m can take on
140
+ * 2^COMB_TEETH distinct values).
141
+ *
142
+ * If m=(d & mask(b)), then table(b, m) is the sum of 2^i * (2*d[i]-1) * G/2, with i
143
+ * iterating over the set bits in mask(b). In our example, table(2, 2^48 + 2^56 + 2^68)
144
+ * would equal (2^48 - 2^52 + 2^56 - 2^60 - 2^64 + 2^68) * G/2.
145
+ *
146
+ * With that, we can rewrite comb(d, G/2) as:
147
+ *
148
+ * 2^0 * (table(0, d>>0 & mask(0)) + ... + table(COMB_BLOCKS-1, d>>0 & mask(COMP_BLOCKS-1)))
149
+ * + 2^1 * (table(0, d>>1 & mask(0)) + ... + table(COMB_BLOCKS-1, d>>1 & mask(COMP_BLOCKS-1)))
150
+ * + 2^2 * (table(0, d>>2 & mask(0)) + ... + table(COMB_BLOCKS-1, d>>2 & mask(COMP_BLOCKS-1)))
151
+ * + ...
152
+ * + 2^(COMB_SPACING-1) * (table(0, d>>(COMB_SPACING-1) & mask(0)) + ...)
153
+ *
154
+ * Or more generically as
155
+ *
156
+ * sum(2^i * sum(table(b, d>>i & mask(b)), b=0..COMB_BLOCKS-1), i=0..COMB_SPACING-1)
157
+ *
158
+ * This is implemented using an outer loop that runs in reverse order over the lines of this
159
+ * equation, which in each iteration runs an inner loop that adds the terms of that line and
160
+ * then doubles the result before proceeding to the next line.
161
+ *
162
+ * In pseudocode:
163
+ * c = infinity
164
+ * for comb_off in range(COMB_SPACING - 1, -1, -1):
165
+ * for block in range(COMB_BLOCKS):
166
+ * c += table(block, (d >> comb_off) & mask(block))
167
+ * if comb_off > 0:
168
+ * c = 2*c
169
+ * return c
170
+ *
171
+ * This computes c = comb(d, G/2), and thus finally R = c + ctx->ge_offset. Note that it would
172
+ * be possible to apply an initial offset instead of a final offset (moving ge_offset to take
173
+ * the place of infinity above), but the chosen approach allows using (in a future improvement)
174
+ * an incomplete addition formula for most of the multiplication.
175
+ *
176
+ * The last question is how to implement the table(b, m) function. For any value of b,
177
+ * m=(d & mask(b)) can only take on at most 2^COMB_TEETH possible values (the last one may have
178
+ * fewer as there mask(b) may exceed the curve order). So we could create COMB_BLOCK tables
179
+ * which contain a value for each such m value.
180
+ *
181
+ * Now note that if m=(d & mask(b)), then flipping the relevant bits of m results in negating
182
+ * the result of table(b, m). This is because table(b,m XOR mask(b)) = table(b, mask(b) - m) =
183
+ * (mask(b) - m - mask(b)/2)*G = (-m + mask(b)/2)*G = -(m - mask(b)/2)*G = -table(b, m).
184
+ * Because of this it suffices to only store the first half of the m values for every b. If an
185
+ * entry from the second half is needed, we look up its bit-flipped version instead, and negate
186
+ * it.
187
+ *
188
+ * secp256k1_ecmult_gen_prec_table[b][index] stores the table(b, m) entries. Index
189
+ * is the relevant mask(b) bits of m packed together without gaps. */
190
+
191
+ /* Outer loop: iterate over comb_off from COMB_SPACING - 1 down to 0. */
192
+ comb_off = COMB_SPACING - 1;
193
+ while (1) {
194
+ uint32_t block;
195
+ uint32_t bit_pos = comb_off;
196
+ /* Inner loop: for each block, add table entries to the result. */
197
+ for (block = 0; block < COMB_BLOCKS; ++block) {
198
+ /* Gather the mask(block)-selected bits of d into bits. They're packed:
199
+ * bits[tooth] = d[(block*COMB_TEETH + tooth)*COMB_SPACING + comb_off]. */
200
+ uint32_t bits = 0, sign, abs, index, tooth;
201
+ /* Instead of reading individual bits here to construct the bits variable,
202
+ * build up the result by xoring rotated reads together. In every iteration,
203
+ * one additional bit is made correct, starting at the bottom. The bits
204
+ * above that contain junk. This reduces leakage by avoiding computations
205
+ * on variables that can have only a low number of possible values (e.g.,
206
+ * just two values when reading a single bit into a variable.) See:
207
+ * https://www.usenix.org/system/files/conference/usenixsecurity18/sec18-alam.pdf
208
+ */
209
+ for (tooth = 0; tooth < COMB_TEETH; ++tooth) {
210
+ /* Construct bitdata s.t. the bottom bit is the bit we'd like to read.
211
+ *
212
+ * We could just set bitdata = recoded[bit_pos >> 5] >> (bit_pos & 0x1f)
213
+ * but this would simply discard the bits that fall off at the bottom,
214
+ * and thus, for example, bitdata could still have only two values if we
215
+ * happen to shift by exactly 31 positions. We use a rotation instead,
216
+ * which ensures that bitdata doesn't loose entropy. This relies on the
217
+ * rotation being atomic, i.e., the compiler emitting an actual rot
218
+ * instruction. */
219
+ uint32_t bitdata = secp256k1_rotr32(recoded[bit_pos >> 5], bit_pos & 0x1f);
220
+
221
+ /* Clear the bit at position tooth, but sssh, don't tell clang. */
222
+ uint32_t volatile vmask = ~(1 << tooth);
223
+ bits &= vmask;
224
+
225
+ /* Write the bit into position tooth (and junk into higher bits). */
226
+ bits ^= bitdata << tooth;
227
+ bit_pos += COMB_SPACING;
228
+ }
229
+
230
+ /* If the top bit of bits is 1, flip them all (corresponding to looking up
231
+ * the negated table value), and remember to negate the result in sign. */
232
+ sign = (bits >> (COMB_TEETH - 1)) & 1;
233
+ abs = (bits ^ -sign) & (COMB_POINTS - 1);
234
+ VERIFY_CHECK(sign == 0 || sign == 1);
235
+ VERIFY_CHECK(abs < COMB_POINTS);
236
+
237
+ /** This uses a conditional move to avoid any secret data in array indexes.
238
+ * _Any_ use of secret indexes has been demonstrated to result in timing
239
+ * sidechannels, even when the cache-line access patterns are uniform.
240
+ * See also:
241
+ * "A word of warning", CHES 2013 Rump Session, by Daniel J. Bernstein and Peter Schwabe
242
+ * (https://cryptojedi.org/peter/data/chesrump-20130822.pdf) and
243
+ * "Cache Attacks and Countermeasures: the Case of AES", RSA 2006,
244
+ * by Dag Arne Osvik, Adi Shamir, and Eran Tromer
245
+ * (https://www.tau.ac.il/~tromer/papers/cache.pdf)
246
+ */
247
+ for (index = 0; index < COMB_POINTS; ++index) {
248
+ secp256k1_ge_storage_cmov(&adds, &secp256k1_ecmult_gen_prec_table[block][index], index == abs);
249
+ }
250
+
251
+ /* Set add=adds or add=-adds, in constant time, based on sign. */
252
+ secp256k1_ge_from_storage(&add, &adds);
253
+ secp256k1_fe_negate(&neg, &add.y, 1);
254
+ secp256k1_fe_cmov(&add.y, &neg, sign);
255
+
256
+ /* Add the looked up and conditionally negated value to r. */
257
+ if (EXPECT(first, 0)) {
258
+ /* If this is the first table lookup, we can skip addition. */
259
+ secp256k1_gej_set_ge(r, &add);
260
+ /* Give the entry a random Z coordinate to blind intermediary results. */
261
+ secp256k1_gej_rescale(r, &ctx->proj_blind);
262
+ first = 0;
263
+ } else {
264
+ secp256k1_gej_add_ge(r, r, &add);
265
+ }
266
+ }
267
+
268
+ /* Double the result, except in the last iteration. */
269
+ if (comb_off-- == 0) break;
270
+ secp256k1_gej_double(r, r);
271
+ }
272
+
273
+ /* Correct for the scalar_offset added at the start (ge_offset = b*G, while b was
274
+ * subtracted from the input scalar gn). */
275
+ secp256k1_gej_add_ge(r, r, &ctx->ge_offset);
276
+
277
+ /* Cleanup. */
278
+ secp256k1_fe_clear(&neg);
279
+ secp256k1_ge_clear(&add);
280
+ secp256k1_memclear(&adds, sizeof(adds));
281
+ secp256k1_memclear(&recoded, sizeof(recoded));
282
+ }
283
+
284
+ /* Setup blinding values for secp256k1_ecmult_gen. */
285
+ static void secp256k1_ecmult_gen_blind(secp256k1_ecmult_gen_context *ctx, const unsigned char *seed32) {
286
+ secp256k1_scalar b;
287
+ secp256k1_scalar diff;
288
+ secp256k1_gej gb;
289
+ secp256k1_fe f;
290
+ unsigned char nonce32[32];
291
+ secp256k1_rfc6979_hmac_sha256 rng;
292
+ unsigned char keydata[64];
293
+
294
+ /* Compute the (2^COMB_BITS - 1)/2 term once. */
295
+ secp256k1_ecmult_gen_scalar_diff(&diff);
296
+
297
+ if (seed32 == NULL) {
298
+ /* When seed is NULL, reset the final point and blinding value. */
299
+ secp256k1_ge_neg(&ctx->ge_offset, &secp256k1_ge_const_g);
300
+ secp256k1_scalar_add(&ctx->scalar_offset, &secp256k1_scalar_one, &diff);
301
+ ctx->proj_blind = secp256k1_fe_one;
302
+ return;
303
+ }
304
+ /* The prior blinding value (if not reset) is chained forward by including it in the hash. */
305
+ secp256k1_scalar_get_b32(keydata, &ctx->scalar_offset);
306
+ /** Using a CSPRNG allows a failure free interface, avoids needing large amounts of random data,
307
+ * and guards against weak or adversarial seeds. This is a simpler and safer interface than
308
+ * asking the caller for blinding values directly and expecting them to retry on failure.
309
+ */
310
+ VERIFY_CHECK(seed32 != NULL);
311
+ memcpy(keydata + 32, seed32, 32);
312
+ secp256k1_rfc6979_hmac_sha256_initialize(&rng, keydata, 64);
313
+ secp256k1_memclear(keydata, sizeof(keydata));
314
+
315
+ /* Compute projective blinding factor (cannot be 0). */
316
+ secp256k1_rfc6979_hmac_sha256_generate(&rng, nonce32, 32);
317
+ secp256k1_fe_set_b32_mod(&f, nonce32);
318
+ secp256k1_fe_cmov(&f, &secp256k1_fe_one, secp256k1_fe_normalizes_to_zero(&f));
319
+ ctx->proj_blind = f;
320
+
321
+ /* For a random blinding value b, set scalar_offset=diff-b, ge_offset=bG */
322
+ secp256k1_rfc6979_hmac_sha256_generate(&rng, nonce32, 32);
323
+ secp256k1_scalar_set_b32(&b, nonce32, NULL);
324
+ /* The blinding value cannot be zero, as that would mean ge_offset = infinity,
325
+ * which secp256k1_gej_add_ge cannot handle. */
326
+ secp256k1_scalar_cmov(&b, &secp256k1_scalar_one, secp256k1_scalar_is_zero(&b));
327
+ secp256k1_rfc6979_hmac_sha256_finalize(&rng);
328
+ secp256k1_ecmult_gen(ctx, &gb, &b);
329
+ secp256k1_scalar_negate(&b, &b);
330
+ secp256k1_scalar_add(&ctx->scalar_offset, &b, &diff);
331
+ secp256k1_ge_set_gej(&ctx->ge_offset, &gb);
332
+
333
+ /* Clean up. */
334
+ secp256k1_memclear(nonce32, sizeof(nonce32));
335
+ secp256k1_scalar_clear(&b);
336
+ secp256k1_gej_clear(&gb);
337
+ secp256k1_fe_clear(&f);
338
+ secp256k1_rfc6979_hmac_sha256_clear(&rng);
339
+ }
340
+
341
+ #endif /* SECP256K1_ECMULT_GEN_IMPL_H */