@qntx/nostr-native 0.0.0-stage → 0.12.1
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.
- package/LICENSE-APACHE +201 -0
- package/LICENSE-MIT +21 -0
- package/NostrNative.podspec +37 -0
- package/README.md +30 -2
- package/android/CMakeLists.txt +38 -0
- package/android/build.gradle +136 -0
- package/android/gradle.properties +4 -0
- package/android/src/main/AndroidManifest.xml +2 -0
- package/android/src/main/cpp/cpp-adapter.cpp +7 -0
- package/android/src/main/java/com/margelo/nitro/nostrnative/NostrNativePackage.java +29 -0
- package/cpp/HybridNostrNative.cpp +52 -0
- package/cpp/HybridNostrNative.hpp +22 -0
- package/cpp/nostr_core.c +128 -0
- package/cpp/nostr_core.h +65 -0
- package/cpp/nostr_native.c +54 -0
- package/cpp/nostr_native.h +47 -0
- package/dist/index.d.mts +15 -0
- package/dist/index.mjs +26 -0
- package/dist/index.mjs.map +1 -0
- package/nitro.json +19 -0
- package/nitrogen/generated/.gitattributes +1 -0
- package/nitrogen/generated/android/NostrNative+autolinking.cmake +81 -0
- package/nitrogen/generated/android/NostrNative+autolinking.gradle +27 -0
- package/nitrogen/generated/android/NostrNativeOnLoad.cpp +49 -0
- package/nitrogen/generated/android/NostrNativeOnLoad.hpp +34 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nostrnative/NostrNativeOnLoad.kt +35 -0
- package/nitrogen/generated/ios/NostrNative+autolinking.rb +62 -0
- package/nitrogen/generated/ios/NostrNative-Swift-Cxx-Bridge.cpp +17 -0
- package/nitrogen/generated/ios/NostrNative-Swift-Cxx-Bridge.hpp +27 -0
- package/nitrogen/generated/ios/NostrNative-Swift-Cxx-Umbrella.hpp +38 -0
- package/nitrogen/generated/ios/NostrNativeAutolinking.mm +35 -0
- package/nitrogen/generated/ios/NostrNativeAutolinking.swift +16 -0
- package/nitrogen/generated/shared/c++/HybridNostrNativeSpec.cpp +23 -0
- package/nitrogen/generated/shared/c++/HybridNostrNativeSpec.hpp +64 -0
- package/package.json +86 -4
- package/react-native.config.js +12 -0
- package/vendor/secp256k1/COPYING +19 -0
- package/vendor/secp256k1/include/secp256k1.h +931 -0
- package/vendor/secp256k1/include/secp256k1_ecdh.h +63 -0
- package/vendor/secp256k1/include/secp256k1_ellswift.h +200 -0
- package/vendor/secp256k1/include/secp256k1_extrakeys.h +250 -0
- package/vendor/secp256k1/include/secp256k1_musig.h +588 -0
- package/vendor/secp256k1/include/secp256k1_preallocated.h +134 -0
- package/vendor/secp256k1/include/secp256k1_recovery.h +123 -0
- package/vendor/secp256k1/include/secp256k1_schnorrsig.h +179 -0
- package/vendor/secp256k1/include/secp256k1_silentpayments.h +396 -0
- package/vendor/secp256k1/src/assumptions.h +87 -0
- package/vendor/secp256k1/src/checkmem.h +117 -0
- package/vendor/secp256k1/src/ecdsa.h +21 -0
- package/vendor/secp256k1/src/ecdsa_impl.h +309 -0
- package/vendor/secp256k1/src/eckey.h +28 -0
- package/vendor/secp256k1/src/eckey_impl.h +94 -0
- package/vendor/secp256k1/src/ecmult.h +64 -0
- package/vendor/secp256k1/src/ecmult_compute_table.h +16 -0
- package/vendor/secp256k1/src/ecmult_compute_table_impl.h +49 -0
- package/vendor/secp256k1/src/ecmult_const.h +38 -0
- package/vendor/secp256k1/src/ecmult_const_impl.h +402 -0
- package/vendor/secp256k1/src/ecmult_gen.h +145 -0
- package/vendor/secp256k1/src/ecmult_gen_compute_table.h +14 -0
- package/vendor/secp256k1/src/ecmult_gen_compute_table_impl.h +108 -0
- package/vendor/secp256k1/src/ecmult_gen_impl.h +347 -0
- package/vendor/secp256k1/src/ecmult_impl.h +869 -0
- package/vendor/secp256k1/src/field.h +351 -0
- package/vendor/secp256k1/src/field_10x26.h +57 -0
- package/vendor/secp256k1/src/field_10x26_impl.h +1210 -0
- package/vendor/secp256k1/src/field_5x52.h +62 -0
- package/vendor/secp256k1/src/field_5x52_impl.h +496 -0
- package/vendor/secp256k1/src/field_5x52_int128_impl.h +274 -0
- package/vendor/secp256k1/src/field_impl.h +457 -0
- package/vendor/secp256k1/src/group.h +218 -0
- package/vendor/secp256k1/src/group_impl.h +1014 -0
- package/vendor/secp256k1/src/hash.h +56 -0
- package/vendor/secp256k1/src/hash_impl.h +397 -0
- package/vendor/secp256k1/src/hsort.h +33 -0
- package/vendor/secp256k1/src/hsort_impl.h +125 -0
- package/vendor/secp256k1/src/int128.h +90 -0
- package/vendor/secp256k1/src/int128_impl.h +18 -0
- package/vendor/secp256k1/src/int128_native.h +19 -0
- package/vendor/secp256k1/src/int128_native_impl.h +94 -0
- package/vendor/secp256k1/src/int128_struct.h +14 -0
- package/vendor/secp256k1/src/int128_struct_impl.h +205 -0
- package/vendor/secp256k1/src/modinv32.h +43 -0
- package/vendor/secp256k1/src/modinv32_impl.h +725 -0
- package/vendor/secp256k1/src/modinv64.h +47 -0
- package/vendor/secp256k1/src/modinv64_impl.h +780 -0
- package/vendor/secp256k1/src/modules/extrakeys/main_impl.h +292 -0
- package/vendor/secp256k1/src/modules/schnorrsig/main_impl.h +256 -0
- package/vendor/secp256k1/src/precomputed_ecmult.c +16456 -0
- package/vendor/secp256k1/src/precomputed_ecmult.h +40 -0
- package/vendor/secp256k1/src/precomputed_ecmult_gen.c +1779 -0
- package/vendor/secp256k1/src/precomputed_ecmult_gen.h +28 -0
- package/vendor/secp256k1/src/scalar.h +105 -0
- package/vendor/secp256k1/src/scalar_4x64.h +19 -0
- package/vendor/secp256k1/src/scalar_4x64_impl.h +1005 -0
- package/vendor/secp256k1/src/scalar_8x32.h +19 -0
- package/vendor/secp256k1/src/scalar_8x32_impl.h +820 -0
- package/vendor/secp256k1/src/scalar_impl.h +321 -0
- package/vendor/secp256k1/src/scalar_low.h +24 -0
- package/vendor/secp256k1/src/scalar_low_impl.h +217 -0
- package/vendor/secp256k1/src/scratch.h +44 -0
- package/vendor/secp256k1/src/scratch_impl.h +99 -0
- package/vendor/secp256k1/src/secp256k1.c +855 -0
- package/vendor/secp256k1/src/selftest.h +41 -0
- package/vendor/secp256k1/src/util.h +479 -0
- package/vendor/secp256k1/src/util_local_visibility.h +12 -0
- package/vendor/secp256k1/vendored.json +6 -0
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/***********************************************************************
|
|
2
|
+
* Copyright (c) 2013, 2014 Pieter Wuille *
|
|
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_FIELD_REPR_H
|
|
8
|
+
#define SECP256K1_FIELD_REPR_H
|
|
9
|
+
|
|
10
|
+
#include <stdint.h>
|
|
11
|
+
|
|
12
|
+
/** This field implementation represents the value as 5 uint64_t limbs in base
|
|
13
|
+
* 2^52. */
|
|
14
|
+
typedef struct {
|
|
15
|
+
/* A field element f represents the sum(i=0..4, f.n[i] << (i*52)) mod p,
|
|
16
|
+
* where p is the field modulus, 2^256 - 2^32 - 977.
|
|
17
|
+
*
|
|
18
|
+
* The individual limbs f.n[i] can exceed 2^52; the field's magnitude roughly
|
|
19
|
+
* corresponds to how much excess is allowed. The value
|
|
20
|
+
* sum(i=0..4, f.n[i] << (i*52)) may exceed p, unless the field element is
|
|
21
|
+
* normalized. */
|
|
22
|
+
uint64_t n[5];
|
|
23
|
+
/*
|
|
24
|
+
* Magnitude m requires:
|
|
25
|
+
* n[i] <= 2 * m * (2^52 - 1) for i=0..3
|
|
26
|
+
* n[4] <= 2 * m * (2^48 - 1)
|
|
27
|
+
*
|
|
28
|
+
* Normalized requires:
|
|
29
|
+
* n[i] <= (2^52 - 1) for i=0..3
|
|
30
|
+
* sum(i=0..4, n[i] << (i*52)) < p
|
|
31
|
+
* (together these imply n[4] <= 2^48 - 1)
|
|
32
|
+
*/
|
|
33
|
+
SECP256K1_FE_VERIFY_FIELDS
|
|
34
|
+
} nostr_native_secp256k1_fe;
|
|
35
|
+
|
|
36
|
+
/* Unpacks a constant into a overlapping multi-limbed FE element. */
|
|
37
|
+
#define SECP256K1_FE_CONST_INNER(d7, d6, d5, d4, d3, d2, d1, d0) { \
|
|
38
|
+
(d0) | (((uint64_t)(d1) & 0xFFFFFUL) << 32), \
|
|
39
|
+
((uint64_t)(d1) >> 20) | (((uint64_t)(d2)) << 12) | (((uint64_t)(d3) & 0xFFUL) << 44), \
|
|
40
|
+
((uint64_t)(d3) >> 8) | (((uint64_t)(d4) & 0xFFFFFFFUL) << 24), \
|
|
41
|
+
((uint64_t)(d4) >> 28) | (((uint64_t)(d5)) << 4) | (((uint64_t)(d6) & 0xFFFFUL) << 36), \
|
|
42
|
+
((uint64_t)(d6) >> 16) | (((uint64_t)(d7)) << 16) \
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
typedef struct {
|
|
46
|
+
uint64_t n[4];
|
|
47
|
+
} nostr_native_secp256k1_fe_storage;
|
|
48
|
+
|
|
49
|
+
#define SECP256K1_FE_STORAGE_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {{ \
|
|
50
|
+
(d0) | (((uint64_t)(d1)) << 32), \
|
|
51
|
+
(d2) | (((uint64_t)(d3)) << 32), \
|
|
52
|
+
(d4) | (((uint64_t)(d5)) << 32), \
|
|
53
|
+
(d6) | (((uint64_t)(d7)) << 32) \
|
|
54
|
+
}}
|
|
55
|
+
|
|
56
|
+
#define SECP256K1_FE_STORAGE_CONST_GET(d) \
|
|
57
|
+
(uint32_t)(d.n[3] >> 32), (uint32_t)d.n[3], \
|
|
58
|
+
(uint32_t)(d.n[2] >> 32), (uint32_t)d.n[2], \
|
|
59
|
+
(uint32_t)(d.n[1] >> 32), (uint32_t)d.n[1], \
|
|
60
|
+
(uint32_t)(d.n[0] >> 32), (uint32_t)d.n[0]
|
|
61
|
+
|
|
62
|
+
#endif /* SECP256K1_FIELD_REPR_H */
|
|
@@ -0,0 +1,496 @@
|
|
|
1
|
+
/***********************************************************************
|
|
2
|
+
* Copyright (c) 2013, 2014 Pieter Wuille *
|
|
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_FIELD_REPR_IMPL_H
|
|
8
|
+
#define SECP256K1_FIELD_REPR_IMPL_H
|
|
9
|
+
|
|
10
|
+
#include "checkmem.h"
|
|
11
|
+
#include "util.h"
|
|
12
|
+
#include "field.h"
|
|
13
|
+
#include "modinv64_impl.h"
|
|
14
|
+
|
|
15
|
+
#include "field_5x52_int128_impl.h"
|
|
16
|
+
|
|
17
|
+
#ifdef VERIFY
|
|
18
|
+
static void nostr_native_secp256k1_fe_impl_verify(const nostr_native_secp256k1_fe *a) {
|
|
19
|
+
const uint64_t *d = a->n;
|
|
20
|
+
int m = a->normalized ? 1 : 2 * a->magnitude;
|
|
21
|
+
/* secp256k1 'p' value defined in "Standards for Efficient Cryptography" (SEC2) 2.7.1. */
|
|
22
|
+
VERIFY_CHECK(d[0] <= 0xFFFFFFFFFFFFFULL * m);
|
|
23
|
+
VERIFY_CHECK(d[1] <= 0xFFFFFFFFFFFFFULL * m);
|
|
24
|
+
VERIFY_CHECK(d[2] <= 0xFFFFFFFFFFFFFULL * m);
|
|
25
|
+
VERIFY_CHECK(d[3] <= 0xFFFFFFFFFFFFFULL * m);
|
|
26
|
+
VERIFY_CHECK(d[4] <= 0x0FFFFFFFFFFFFULL * m);
|
|
27
|
+
if (a->normalized) {
|
|
28
|
+
if ((d[4] == 0x0FFFFFFFFFFFFULL) && ((d[3] & d[2] & d[1]) == 0xFFFFFFFFFFFFFULL)) {
|
|
29
|
+
VERIFY_CHECK(d[0] < 0xFFFFEFFFFFC2FULL);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
#endif
|
|
34
|
+
|
|
35
|
+
static void nostr_native_secp256k1_fe_impl_get_bounds(nostr_native_secp256k1_fe *r, int m) {
|
|
36
|
+
r->n[0] = 0xFFFFFFFFFFFFFULL * 2 * m;
|
|
37
|
+
r->n[1] = 0xFFFFFFFFFFFFFULL * 2 * m;
|
|
38
|
+
r->n[2] = 0xFFFFFFFFFFFFFULL * 2 * m;
|
|
39
|
+
r->n[3] = 0xFFFFFFFFFFFFFULL * 2 * m;
|
|
40
|
+
r->n[4] = 0x0FFFFFFFFFFFFULL * 2 * m;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
static void nostr_native_secp256k1_fe_impl_normalize(nostr_native_secp256k1_fe *r) {
|
|
44
|
+
uint64_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4];
|
|
45
|
+
|
|
46
|
+
/* Reduce t4 at the start so there will be at most a single carry from the first pass */
|
|
47
|
+
uint64_t m;
|
|
48
|
+
uint64_t x = t4 >> 48; t4 &= 0x0FFFFFFFFFFFFULL;
|
|
49
|
+
|
|
50
|
+
/* The first pass ensures the magnitude is 1, ... */
|
|
51
|
+
t0 += x * 0x1000003D1ULL;
|
|
52
|
+
t1 += (t0 >> 52); t0 &= 0xFFFFFFFFFFFFFULL;
|
|
53
|
+
t2 += (t1 >> 52); t1 &= 0xFFFFFFFFFFFFFULL; m = t1;
|
|
54
|
+
t3 += (t2 >> 52); t2 &= 0xFFFFFFFFFFFFFULL; m &= t2;
|
|
55
|
+
t4 += (t3 >> 52); t3 &= 0xFFFFFFFFFFFFFULL; m &= t3;
|
|
56
|
+
|
|
57
|
+
/* ... except for a possible carry at bit 48 of t4 (i.e. bit 256 of the field element) */
|
|
58
|
+
VERIFY_CHECK(t4 >> 49 == 0);
|
|
59
|
+
|
|
60
|
+
/* At most a single final reduction is needed; check if the value is >= the field characteristic */
|
|
61
|
+
x = (t4 >> 48) | ((t4 == 0x0FFFFFFFFFFFFULL) & (m == 0xFFFFFFFFFFFFFULL)
|
|
62
|
+
& (t0 >= 0xFFFFEFFFFFC2FULL));
|
|
63
|
+
|
|
64
|
+
/* Apply the final reduction (for constant-time behaviour, we do it always) */
|
|
65
|
+
t0 += x * 0x1000003D1ULL;
|
|
66
|
+
t1 += (t0 >> 52); t0 &= 0xFFFFFFFFFFFFFULL;
|
|
67
|
+
t2 += (t1 >> 52); t1 &= 0xFFFFFFFFFFFFFULL;
|
|
68
|
+
t3 += (t2 >> 52); t2 &= 0xFFFFFFFFFFFFFULL;
|
|
69
|
+
t4 += (t3 >> 52); t3 &= 0xFFFFFFFFFFFFFULL;
|
|
70
|
+
|
|
71
|
+
/* If t4 didn't carry to bit 48 already, then it should have after any final reduction */
|
|
72
|
+
VERIFY_CHECK(t4 >> 48 == x);
|
|
73
|
+
|
|
74
|
+
/* Mask off the possible multiple of 2^256 from the final reduction */
|
|
75
|
+
t4 &= 0x0FFFFFFFFFFFFULL;
|
|
76
|
+
|
|
77
|
+
r->n[0] = t0; r->n[1] = t1; r->n[2] = t2; r->n[3] = t3; r->n[4] = t4;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
static void nostr_native_secp256k1_fe_impl_normalize_weak(nostr_native_secp256k1_fe *r) {
|
|
81
|
+
uint64_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4];
|
|
82
|
+
|
|
83
|
+
/* Reduce t4 at the start so there will be at most a single carry from the first pass */
|
|
84
|
+
uint64_t x = t4 >> 48; t4 &= 0x0FFFFFFFFFFFFULL;
|
|
85
|
+
|
|
86
|
+
/* The first pass ensures the magnitude is 1, ... */
|
|
87
|
+
t0 += x * 0x1000003D1ULL;
|
|
88
|
+
t1 += (t0 >> 52); t0 &= 0xFFFFFFFFFFFFFULL;
|
|
89
|
+
t2 += (t1 >> 52); t1 &= 0xFFFFFFFFFFFFFULL;
|
|
90
|
+
t3 += (t2 >> 52); t2 &= 0xFFFFFFFFFFFFFULL;
|
|
91
|
+
t4 += (t3 >> 52); t3 &= 0xFFFFFFFFFFFFFULL;
|
|
92
|
+
|
|
93
|
+
/* ... except for a possible carry at bit 48 of t4 (i.e. bit 256 of the field element) */
|
|
94
|
+
VERIFY_CHECK(t4 >> 49 == 0);
|
|
95
|
+
|
|
96
|
+
r->n[0] = t0; r->n[1] = t1; r->n[2] = t2; r->n[3] = t3; r->n[4] = t4;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
static void nostr_native_secp256k1_fe_impl_normalize_var(nostr_native_secp256k1_fe *r) {
|
|
100
|
+
uint64_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4];
|
|
101
|
+
|
|
102
|
+
/* Reduce t4 at the start so there will be at most a single carry from the first pass */
|
|
103
|
+
uint64_t m;
|
|
104
|
+
uint64_t x = t4 >> 48; t4 &= 0x0FFFFFFFFFFFFULL;
|
|
105
|
+
|
|
106
|
+
/* The first pass ensures the magnitude is 1, ... */
|
|
107
|
+
t0 += x * 0x1000003D1ULL;
|
|
108
|
+
t1 += (t0 >> 52); t0 &= 0xFFFFFFFFFFFFFULL;
|
|
109
|
+
t2 += (t1 >> 52); t1 &= 0xFFFFFFFFFFFFFULL; m = t1;
|
|
110
|
+
t3 += (t2 >> 52); t2 &= 0xFFFFFFFFFFFFFULL; m &= t2;
|
|
111
|
+
t4 += (t3 >> 52); t3 &= 0xFFFFFFFFFFFFFULL; m &= t3;
|
|
112
|
+
|
|
113
|
+
/* ... except for a possible carry at bit 48 of t4 (i.e. bit 256 of the field element) */
|
|
114
|
+
VERIFY_CHECK(t4 >> 49 == 0);
|
|
115
|
+
|
|
116
|
+
/* At most a single final reduction is needed; check if the value is >= the field characteristic */
|
|
117
|
+
x = (t4 >> 48) | ((t4 == 0x0FFFFFFFFFFFFULL) & (m == 0xFFFFFFFFFFFFFULL)
|
|
118
|
+
& (t0 >= 0xFFFFEFFFFFC2FULL));
|
|
119
|
+
|
|
120
|
+
if (x) {
|
|
121
|
+
t0 += 0x1000003D1ULL;
|
|
122
|
+
t1 += (t0 >> 52); t0 &= 0xFFFFFFFFFFFFFULL;
|
|
123
|
+
t2 += (t1 >> 52); t1 &= 0xFFFFFFFFFFFFFULL;
|
|
124
|
+
t3 += (t2 >> 52); t2 &= 0xFFFFFFFFFFFFFULL;
|
|
125
|
+
t4 += (t3 >> 52); t3 &= 0xFFFFFFFFFFFFFULL;
|
|
126
|
+
|
|
127
|
+
/* If t4 didn't carry to bit 48 already, then it should have after any final reduction */
|
|
128
|
+
VERIFY_CHECK(t4 >> 48 == x);
|
|
129
|
+
|
|
130
|
+
/* Mask off the possible multiple of 2^256 from the final reduction */
|
|
131
|
+
t4 &= 0x0FFFFFFFFFFFFULL;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
r->n[0] = t0; r->n[1] = t1; r->n[2] = t2; r->n[3] = t3; r->n[4] = t4;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
static int nostr_native_secp256k1_fe_impl_normalizes_to_zero(const nostr_native_secp256k1_fe *r) {
|
|
138
|
+
uint64_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4];
|
|
139
|
+
|
|
140
|
+
/* z0 tracks a possible raw value of 0, z1 tracks a possible raw value of P */
|
|
141
|
+
uint64_t z0, z1;
|
|
142
|
+
|
|
143
|
+
/* Reduce t4 at the start so there will be at most a single carry from the first pass */
|
|
144
|
+
uint64_t x = t4 >> 48; t4 &= 0x0FFFFFFFFFFFFULL;
|
|
145
|
+
|
|
146
|
+
/* The first pass ensures the magnitude is 1, ... */
|
|
147
|
+
t0 += x * 0x1000003D1ULL;
|
|
148
|
+
t1 += (t0 >> 52); t0 &= 0xFFFFFFFFFFFFFULL; z0 = t0; z1 = t0 ^ 0x1000003D0ULL;
|
|
149
|
+
t2 += (t1 >> 52); t1 &= 0xFFFFFFFFFFFFFULL; z0 |= t1; z1 &= t1;
|
|
150
|
+
t3 += (t2 >> 52); t2 &= 0xFFFFFFFFFFFFFULL; z0 |= t2; z1 &= t2;
|
|
151
|
+
t4 += (t3 >> 52); t3 &= 0xFFFFFFFFFFFFFULL; z0 |= t3; z1 &= t3;
|
|
152
|
+
z0 |= t4; z1 &= t4 ^ 0xF000000000000ULL;
|
|
153
|
+
|
|
154
|
+
/* ... except for a possible carry at bit 48 of t4 (i.e. bit 256 of the field element) */
|
|
155
|
+
VERIFY_CHECK(t4 >> 49 == 0);
|
|
156
|
+
|
|
157
|
+
return (z0 == 0) | (z1 == 0xFFFFFFFFFFFFFULL);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
static int nostr_native_secp256k1_fe_impl_normalizes_to_zero_var(const nostr_native_secp256k1_fe *r) {
|
|
161
|
+
uint64_t t0, t1, t2, t3, t4;
|
|
162
|
+
uint64_t z0, z1;
|
|
163
|
+
uint64_t x;
|
|
164
|
+
|
|
165
|
+
t0 = r->n[0];
|
|
166
|
+
t4 = r->n[4];
|
|
167
|
+
|
|
168
|
+
/* Reduce t4 at the start so there will be at most a single carry from the first pass */
|
|
169
|
+
x = t4 >> 48;
|
|
170
|
+
|
|
171
|
+
/* The first pass ensures the magnitude is 1, ... */
|
|
172
|
+
t0 += x * 0x1000003D1ULL;
|
|
173
|
+
|
|
174
|
+
/* z0 tracks a possible raw value of 0, z1 tracks a possible raw value of P */
|
|
175
|
+
z0 = t0 & 0xFFFFFFFFFFFFFULL;
|
|
176
|
+
z1 = z0 ^ 0x1000003D0ULL;
|
|
177
|
+
|
|
178
|
+
/* Fast return path should catch the majority of cases */
|
|
179
|
+
if ((z0 != 0ULL) & (z1 != 0xFFFFFFFFFFFFFULL)) {
|
|
180
|
+
return 0;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
t1 = r->n[1];
|
|
184
|
+
t2 = r->n[2];
|
|
185
|
+
t3 = r->n[3];
|
|
186
|
+
|
|
187
|
+
t4 &= 0x0FFFFFFFFFFFFULL;
|
|
188
|
+
|
|
189
|
+
t1 += (t0 >> 52);
|
|
190
|
+
t2 += (t1 >> 52); t1 &= 0xFFFFFFFFFFFFFULL; z0 |= t1; z1 &= t1;
|
|
191
|
+
t3 += (t2 >> 52); t2 &= 0xFFFFFFFFFFFFFULL; z0 |= t2; z1 &= t2;
|
|
192
|
+
t4 += (t3 >> 52); t3 &= 0xFFFFFFFFFFFFFULL; z0 |= t3; z1 &= t3;
|
|
193
|
+
z0 |= t4; z1 &= t4 ^ 0xF000000000000ULL;
|
|
194
|
+
|
|
195
|
+
/* ... except for a possible carry at bit 48 of t4 (i.e. bit 256 of the field element) */
|
|
196
|
+
VERIFY_CHECK(t4 >> 49 == 0);
|
|
197
|
+
|
|
198
|
+
return (z0 == 0) | (z1 == 0xFFFFFFFFFFFFFULL);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
SECP256K1_INLINE static void nostr_native_secp256k1_fe_impl_set_int(nostr_native_secp256k1_fe *r, int a) {
|
|
202
|
+
r->n[0] = a;
|
|
203
|
+
r->n[1] = r->n[2] = r->n[3] = r->n[4] = 0;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
SECP256K1_INLINE static int nostr_native_secp256k1_fe_impl_is_zero(const nostr_native_secp256k1_fe *a) {
|
|
207
|
+
const uint64_t *t = a->n;
|
|
208
|
+
return (t[0] | t[1] | t[2] | t[3] | t[4]) == 0;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
SECP256K1_INLINE static int nostr_native_secp256k1_fe_impl_is_odd(const nostr_native_secp256k1_fe *a) {
|
|
212
|
+
return a->n[0] & 1;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
static int nostr_native_secp256k1_fe_impl_cmp_var(const nostr_native_secp256k1_fe *a, const nostr_native_secp256k1_fe *b) {
|
|
216
|
+
int i;
|
|
217
|
+
for (i = 4; i >= 0; i--) {
|
|
218
|
+
if (a->n[i] > b->n[i]) {
|
|
219
|
+
return 1;
|
|
220
|
+
}
|
|
221
|
+
if (a->n[i] < b->n[i]) {
|
|
222
|
+
return -1;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
return 0;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
static void nostr_native_secp256k1_fe_impl_set_b32_mod(nostr_native_secp256k1_fe *r, const unsigned char *a) {
|
|
229
|
+
r->n[0] = (uint64_t)a[31]
|
|
230
|
+
| ((uint64_t)a[30] << 8)
|
|
231
|
+
| ((uint64_t)a[29] << 16)
|
|
232
|
+
| ((uint64_t)a[28] << 24)
|
|
233
|
+
| ((uint64_t)a[27] << 32)
|
|
234
|
+
| ((uint64_t)a[26] << 40)
|
|
235
|
+
| ((uint64_t)(a[25] & 0xF) << 48);
|
|
236
|
+
r->n[1] = (uint64_t)((a[25] >> 4) & 0xF)
|
|
237
|
+
| ((uint64_t)a[24] << 4)
|
|
238
|
+
| ((uint64_t)a[23] << 12)
|
|
239
|
+
| ((uint64_t)a[22] << 20)
|
|
240
|
+
| ((uint64_t)a[21] << 28)
|
|
241
|
+
| ((uint64_t)a[20] << 36)
|
|
242
|
+
| ((uint64_t)a[19] << 44);
|
|
243
|
+
r->n[2] = (uint64_t)a[18]
|
|
244
|
+
| ((uint64_t)a[17] << 8)
|
|
245
|
+
| ((uint64_t)a[16] << 16)
|
|
246
|
+
| ((uint64_t)a[15] << 24)
|
|
247
|
+
| ((uint64_t)a[14] << 32)
|
|
248
|
+
| ((uint64_t)a[13] << 40)
|
|
249
|
+
| ((uint64_t)(a[12] & 0xF) << 48);
|
|
250
|
+
r->n[3] = (uint64_t)((a[12] >> 4) & 0xF)
|
|
251
|
+
| ((uint64_t)a[11] << 4)
|
|
252
|
+
| ((uint64_t)a[10] << 12)
|
|
253
|
+
| ((uint64_t)a[9] << 20)
|
|
254
|
+
| ((uint64_t)a[8] << 28)
|
|
255
|
+
| ((uint64_t)a[7] << 36)
|
|
256
|
+
| ((uint64_t)a[6] << 44);
|
|
257
|
+
r->n[4] = (uint64_t)a[5]
|
|
258
|
+
| ((uint64_t)a[4] << 8)
|
|
259
|
+
| ((uint64_t)a[3] << 16)
|
|
260
|
+
| ((uint64_t)a[2] << 24)
|
|
261
|
+
| ((uint64_t)a[1] << 32)
|
|
262
|
+
| ((uint64_t)a[0] << 40);
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
static int nostr_native_secp256k1_fe_impl_set_b32_limit(nostr_native_secp256k1_fe *r, const unsigned char *a) {
|
|
266
|
+
nostr_native_secp256k1_fe_impl_set_b32_mod(r, a);
|
|
267
|
+
return !((r->n[4] == 0x0FFFFFFFFFFFFULL) & ((r->n[3] & r->n[2] & r->n[1]) == 0xFFFFFFFFFFFFFULL) & (r->n[0] >= 0xFFFFEFFFFFC2FULL));
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/** Convert a field element to a 32-byte big endian value. Requires the input to be normalized */
|
|
271
|
+
static void nostr_native_secp256k1_fe_impl_get_b32(unsigned char *r, const nostr_native_secp256k1_fe *a) {
|
|
272
|
+
nostr_native_secp256k1_write_be64(&r[0], (a->n[4] << 16) | (a->n[3] >> 36));
|
|
273
|
+
nostr_native_secp256k1_write_be64(&r[8], (a->n[3] << 28) | (a->n[2] >> 24));
|
|
274
|
+
nostr_native_secp256k1_write_be64(&r[16], (a->n[2] << 40) | (a->n[1] >> 12));
|
|
275
|
+
nostr_native_secp256k1_write_be64(&r[24], (a->n[1] << 52) | a->n[0]);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
SECP256K1_INLINE static void nostr_native_secp256k1_fe_impl_negate_unchecked(nostr_native_secp256k1_fe *r, const nostr_native_secp256k1_fe *a, int m) {
|
|
279
|
+
/* For all legal values of m (0..31), the following properties hold: */
|
|
280
|
+
VERIFY_CHECK(0xFFFFEFFFFFC2FULL * 2 * (m + 1) >= 0xFFFFFFFFFFFFFULL * 2 * m);
|
|
281
|
+
VERIFY_CHECK(0xFFFFFFFFFFFFFULL * 2 * (m + 1) >= 0xFFFFFFFFFFFFFULL * 2 * m);
|
|
282
|
+
VERIFY_CHECK(0x0FFFFFFFFFFFFULL * 2 * (m + 1) >= 0x0FFFFFFFFFFFFULL * 2 * m);
|
|
283
|
+
|
|
284
|
+
/* Due to the properties above, the left hand in the subtractions below is never less than
|
|
285
|
+
* the right hand. */
|
|
286
|
+
r->n[0] = 0xFFFFEFFFFFC2FULL * 2 * (m + 1) - a->n[0];
|
|
287
|
+
r->n[1] = 0xFFFFFFFFFFFFFULL * 2 * (m + 1) - a->n[1];
|
|
288
|
+
r->n[2] = 0xFFFFFFFFFFFFFULL * 2 * (m + 1) - a->n[2];
|
|
289
|
+
r->n[3] = 0xFFFFFFFFFFFFFULL * 2 * (m + 1) - a->n[3];
|
|
290
|
+
r->n[4] = 0x0FFFFFFFFFFFFULL * 2 * (m + 1) - a->n[4];
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
SECP256K1_INLINE static void nostr_native_secp256k1_fe_impl_mul_int_unchecked(nostr_native_secp256k1_fe *r, int a) {
|
|
294
|
+
r->n[0] *= a;
|
|
295
|
+
r->n[1] *= a;
|
|
296
|
+
r->n[2] *= a;
|
|
297
|
+
r->n[3] *= a;
|
|
298
|
+
r->n[4] *= a;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
SECP256K1_INLINE static void nostr_native_secp256k1_fe_impl_add_int(nostr_native_secp256k1_fe *r, int a) {
|
|
302
|
+
r->n[0] += a;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
SECP256K1_INLINE static void nostr_native_secp256k1_fe_impl_add(nostr_native_secp256k1_fe *r, const nostr_native_secp256k1_fe *a) {
|
|
306
|
+
r->n[0] += a->n[0];
|
|
307
|
+
r->n[1] += a->n[1];
|
|
308
|
+
r->n[2] += a->n[2];
|
|
309
|
+
r->n[3] += a->n[3];
|
|
310
|
+
r->n[4] += a->n[4];
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
SECP256K1_FORCE_INLINE static void nostr_native_secp256k1_fe_impl_mul(nostr_native_secp256k1_fe *r, const nostr_native_secp256k1_fe *a, const nostr_native_secp256k1_fe * SECP256K1_RESTRICT b) {
|
|
314
|
+
nostr_native_secp256k1_fe_mul_inner(r->n, a->n, b->n);
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
SECP256K1_FORCE_INLINE static void nostr_native_secp256k1_fe_impl_sqr(nostr_native_secp256k1_fe *r, const nostr_native_secp256k1_fe *a) {
|
|
318
|
+
nostr_native_secp256k1_fe_sqr_inner(r->n, a->n);
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
SECP256K1_INLINE static void nostr_native_secp256k1_fe_impl_cmov(nostr_native_secp256k1_fe *r, const nostr_native_secp256k1_fe *a, int flag) {
|
|
322
|
+
uint64_t mask0, mask1;
|
|
323
|
+
volatile int vflag = flag;
|
|
324
|
+
VERIFY_CHECK(flag == 0 || flag == 1);
|
|
325
|
+
SECP256K1_CHECKMEM_CHECK_VERIFY(r->n, sizeof(r->n));
|
|
326
|
+
mask0 = vflag + ~((uint64_t)0);
|
|
327
|
+
mask1 = ~mask0;
|
|
328
|
+
r->n[0] = (r->n[0] & mask0) | (a->n[0] & mask1);
|
|
329
|
+
r->n[1] = (r->n[1] & mask0) | (a->n[1] & mask1);
|
|
330
|
+
r->n[2] = (r->n[2] & mask0) | (a->n[2] & mask1);
|
|
331
|
+
r->n[3] = (r->n[3] & mask0) | (a->n[3] & mask1);
|
|
332
|
+
r->n[4] = (r->n[4] & mask0) | (a->n[4] & mask1);
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
static SECP256K1_INLINE void nostr_native_secp256k1_fe_impl_half(nostr_native_secp256k1_fe *r) {
|
|
336
|
+
uint64_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4];
|
|
337
|
+
uint64_t one = (uint64_t)1;
|
|
338
|
+
uint64_t mask = -(t0 & one) >> 12;
|
|
339
|
+
|
|
340
|
+
/* Bounds analysis (over the rationals).
|
|
341
|
+
*
|
|
342
|
+
* Let m = r->magnitude
|
|
343
|
+
* C = 0xFFFFFFFFFFFFFULL * 2
|
|
344
|
+
* D = 0x0FFFFFFFFFFFFULL * 2
|
|
345
|
+
*
|
|
346
|
+
* Initial bounds: t0..t3 <= C * m
|
|
347
|
+
* t4 <= D * m
|
|
348
|
+
*/
|
|
349
|
+
|
|
350
|
+
t0 += 0xFFFFEFFFFFC2FULL & mask;
|
|
351
|
+
t1 += mask;
|
|
352
|
+
t2 += mask;
|
|
353
|
+
t3 += mask;
|
|
354
|
+
t4 += mask >> 4;
|
|
355
|
+
|
|
356
|
+
VERIFY_CHECK((t0 & one) == 0);
|
|
357
|
+
|
|
358
|
+
/* t0..t3: added <= C/2
|
|
359
|
+
* t4: added <= D/2
|
|
360
|
+
*
|
|
361
|
+
* Current bounds: t0..t3 <= C * (m + 1/2)
|
|
362
|
+
* t4 <= D * (m + 1/2)
|
|
363
|
+
*/
|
|
364
|
+
|
|
365
|
+
r->n[0] = (t0 >> 1) + ((t1 & one) << 51);
|
|
366
|
+
r->n[1] = (t1 >> 1) + ((t2 & one) << 51);
|
|
367
|
+
r->n[2] = (t2 >> 1) + ((t3 & one) << 51);
|
|
368
|
+
r->n[3] = (t3 >> 1) + ((t4 & one) << 51);
|
|
369
|
+
r->n[4] = (t4 >> 1);
|
|
370
|
+
|
|
371
|
+
/* t0..t3: shifted right and added <= C/4 + 1/2
|
|
372
|
+
* t4: shifted right
|
|
373
|
+
*
|
|
374
|
+
* Current bounds: t0..t3 <= C * (m/2 + 1/2)
|
|
375
|
+
* t4 <= D * (m/2 + 1/4)
|
|
376
|
+
*
|
|
377
|
+
* Therefore the output magnitude (M) has to be set such that:
|
|
378
|
+
* t0..t3: C * M >= C * (m/2 + 1/2)
|
|
379
|
+
* t4: D * M >= D * (m/2 + 1/4)
|
|
380
|
+
*
|
|
381
|
+
* It suffices for all limbs that, for any input magnitude m:
|
|
382
|
+
* M >= m/2 + 1/2
|
|
383
|
+
*
|
|
384
|
+
* and since we want the smallest such integer value for M:
|
|
385
|
+
* M == floor(m/2) + 1
|
|
386
|
+
*/
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
static SECP256K1_INLINE void nostr_native_secp256k1_fe_storage_cmov(nostr_native_secp256k1_fe_storage *r, const nostr_native_secp256k1_fe_storage *a, int flag) {
|
|
390
|
+
uint64_t mask0, mask1;
|
|
391
|
+
volatile int vflag = flag;
|
|
392
|
+
VERIFY_CHECK(flag == 0 || flag == 1);
|
|
393
|
+
SECP256K1_CHECKMEM_CHECK_VERIFY(r->n, sizeof(r->n));
|
|
394
|
+
mask0 = vflag + ~((uint64_t)0);
|
|
395
|
+
mask1 = ~mask0;
|
|
396
|
+
r->n[0] = (r->n[0] & mask0) | (a->n[0] & mask1);
|
|
397
|
+
r->n[1] = (r->n[1] & mask0) | (a->n[1] & mask1);
|
|
398
|
+
r->n[2] = (r->n[2] & mask0) | (a->n[2] & mask1);
|
|
399
|
+
r->n[3] = (r->n[3] & mask0) | (a->n[3] & mask1);
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
static void nostr_native_secp256k1_fe_impl_to_storage(nostr_native_secp256k1_fe_storage *r, const nostr_native_secp256k1_fe *a) {
|
|
403
|
+
r->n[0] = a->n[0] | a->n[1] << 52;
|
|
404
|
+
r->n[1] = a->n[1] >> 12 | a->n[2] << 40;
|
|
405
|
+
r->n[2] = a->n[2] >> 24 | a->n[3] << 28;
|
|
406
|
+
r->n[3] = a->n[3] >> 36 | a->n[4] << 16;
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
static SECP256K1_INLINE void nostr_native_secp256k1_fe_impl_from_storage(nostr_native_secp256k1_fe *r, const nostr_native_secp256k1_fe_storage *a) {
|
|
410
|
+
r->n[0] = a->n[0] & 0xFFFFFFFFFFFFFULL;
|
|
411
|
+
r->n[1] = a->n[0] >> 52 | ((a->n[1] << 12) & 0xFFFFFFFFFFFFFULL);
|
|
412
|
+
r->n[2] = a->n[1] >> 40 | ((a->n[2] << 24) & 0xFFFFFFFFFFFFFULL);
|
|
413
|
+
r->n[3] = a->n[2] >> 28 | ((a->n[3] << 36) & 0xFFFFFFFFFFFFFULL);
|
|
414
|
+
r->n[4] = a->n[3] >> 16;
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
static void nostr_native_secp256k1_fe_from_signed62(nostr_native_secp256k1_fe *r, const nostr_native_secp256k1_modinv64_signed62 *a) {
|
|
418
|
+
const uint64_t M52 = UINT64_MAX >> 12;
|
|
419
|
+
const uint64_t a0 = a->v[0], a1 = a->v[1], a2 = a->v[2], a3 = a->v[3], a4 = a->v[4];
|
|
420
|
+
|
|
421
|
+
/* The output from nostr_native_secp256k1_modinv64{_var} should be normalized to range [0,modulus), and
|
|
422
|
+
* have limbs in [0,2^62). The modulus is < 2^256, so the top limb must be below 2^(256-62*4).
|
|
423
|
+
*/
|
|
424
|
+
VERIFY_CHECK(a0 >> 62 == 0);
|
|
425
|
+
VERIFY_CHECK(a1 >> 62 == 0);
|
|
426
|
+
VERIFY_CHECK(a2 >> 62 == 0);
|
|
427
|
+
VERIFY_CHECK(a3 >> 62 == 0);
|
|
428
|
+
VERIFY_CHECK(a4 >> 8 == 0);
|
|
429
|
+
|
|
430
|
+
r->n[0] = a0 & M52;
|
|
431
|
+
r->n[1] = (a0 >> 52 | a1 << 10) & M52;
|
|
432
|
+
r->n[2] = (a1 >> 42 | a2 << 20) & M52;
|
|
433
|
+
r->n[3] = (a2 >> 32 | a3 << 30) & M52;
|
|
434
|
+
r->n[4] = (a3 >> 22 | a4 << 40);
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
static void nostr_native_secp256k1_fe_to_signed62(nostr_native_secp256k1_modinv64_signed62 *r, const nostr_native_secp256k1_fe *a) {
|
|
438
|
+
const uint64_t M62 = UINT64_MAX >> 2;
|
|
439
|
+
const uint64_t a0 = a->n[0], a1 = a->n[1], a2 = a->n[2], a3 = a->n[3], a4 = a->n[4];
|
|
440
|
+
|
|
441
|
+
r->v[0] = (a0 | a1 << 52) & M62;
|
|
442
|
+
r->v[1] = (a1 >> 10 | a2 << 42) & M62;
|
|
443
|
+
r->v[2] = (a2 >> 20 | a3 << 32) & M62;
|
|
444
|
+
r->v[3] = (a3 >> 30 | a4 << 22) & M62;
|
|
445
|
+
r->v[4] = a4 >> 40;
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
static const nostr_native_secp256k1_modinv64_modinfo nostr_native_secp256k1_const_modinfo_fe = {
|
|
449
|
+
{{-0x1000003D1LL, 0, 0, 0, 256}},
|
|
450
|
+
0x27C7F6E22DDACACFLL
|
|
451
|
+
};
|
|
452
|
+
|
|
453
|
+
static void nostr_native_secp256k1_fe_impl_inv(nostr_native_secp256k1_fe *r, const nostr_native_secp256k1_fe *x) {
|
|
454
|
+
nostr_native_secp256k1_fe tmp = *x;
|
|
455
|
+
nostr_native_secp256k1_modinv64_signed62 s;
|
|
456
|
+
|
|
457
|
+
nostr_native_secp256k1_fe_normalize(&tmp);
|
|
458
|
+
nostr_native_secp256k1_fe_to_signed62(&s, &tmp);
|
|
459
|
+
nostr_native_secp256k1_modinv64(&s, &nostr_native_secp256k1_const_modinfo_fe);
|
|
460
|
+
nostr_native_secp256k1_fe_from_signed62(r, &s);
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
static void nostr_native_secp256k1_fe_impl_inv_var(nostr_native_secp256k1_fe *r, const nostr_native_secp256k1_fe *x) {
|
|
464
|
+
nostr_native_secp256k1_fe tmp = *x;
|
|
465
|
+
nostr_native_secp256k1_modinv64_signed62 s;
|
|
466
|
+
|
|
467
|
+
nostr_native_secp256k1_fe_normalize_var(&tmp);
|
|
468
|
+
nostr_native_secp256k1_fe_to_signed62(&s, &tmp);
|
|
469
|
+
nostr_native_secp256k1_modinv64_var(&s, &nostr_native_secp256k1_const_modinfo_fe);
|
|
470
|
+
nostr_native_secp256k1_fe_from_signed62(r, &s);
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
static int nostr_native_secp256k1_fe_impl_is_square_var(const nostr_native_secp256k1_fe *x) {
|
|
474
|
+
nostr_native_secp256k1_fe tmp;
|
|
475
|
+
nostr_native_secp256k1_modinv64_signed62 s;
|
|
476
|
+
int jac, ret;
|
|
477
|
+
|
|
478
|
+
tmp = *x;
|
|
479
|
+
nostr_native_secp256k1_fe_normalize_var(&tmp);
|
|
480
|
+
/* nostr_native_secp256k1_jacobi64_maybe_var cannot deal with input 0. */
|
|
481
|
+
if (nostr_native_secp256k1_fe_is_zero(&tmp)) return 1;
|
|
482
|
+
nostr_native_secp256k1_fe_to_signed62(&s, &tmp);
|
|
483
|
+
jac = nostr_native_secp256k1_jacobi64_maybe_var(&s, &nostr_native_secp256k1_const_modinfo_fe);
|
|
484
|
+
if (jac == 0) {
|
|
485
|
+
/* nostr_native_secp256k1_jacobi64_maybe_var failed to compute the Jacobi symbol. Fall back
|
|
486
|
+
* to computing a square root. This should be extremely rare with random
|
|
487
|
+
* input (except in VERIFY mode, where a lower iteration count is used). */
|
|
488
|
+
nostr_native_secp256k1_fe dummy;
|
|
489
|
+
ret = nostr_native_secp256k1_fe_sqrt(&dummy, &tmp);
|
|
490
|
+
} else {
|
|
491
|
+
ret = jac >= 0;
|
|
492
|
+
}
|
|
493
|
+
return ret;
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
#endif /* SECP256K1_FIELD_REPR_IMPL_H */
|