@pbnjam/bandersnatch 0.7.2-rc1 → 0.7.2-rc2
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/.github/workflows/docs.yml +0 -2
- package/package.json +2 -2
- package/src/curve.ts +23 -15
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pbnjam/bandersnatch",
|
|
3
|
-
"version": "0.7.2-
|
|
3
|
+
"version": "0.7.2-rc2",
|
|
4
4
|
"description": "Bandersnatch elliptic curve implementation",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|
|
9
|
-
"url": "https://github.com/Esscrypt/bandersnatch.git"
|
|
9
|
+
"url": "git+https://github.com/Esscrypt/bandersnatch.git"
|
|
10
10
|
},
|
|
11
11
|
"homepage": "https://github.com/Esscrypt/bandersnatch",
|
|
12
12
|
"bugs": {
|
package/src/curve.ts
CHANGED
|
@@ -98,16 +98,22 @@ export class BandersnatchCurve {
|
|
|
98
98
|
* 1. Extracts the y-coordinate from the first 31 bytes (little-endian)
|
|
99
99
|
* 2. Extracts the x-coordinate sign from bit 7 of the last byte
|
|
100
100
|
* 3. Computes the x-coordinate from y using the curve equation
|
|
101
|
-
* 4.
|
|
101
|
+
* 4. Optionally validates the point is in the prime subgroup G
|
|
102
102
|
*
|
|
103
103
|
* @param bytes - Compressed point bytes in arkworks format (32 bytes)
|
|
104
|
+
* @param validateSubgroup - Whether to validate point is in prime subgroup (default: true)
|
|
105
|
+
* Set to false for faster validation when only checking if bytes
|
|
106
|
+
* represent a valid curve point (e.g., for padding point replacement)
|
|
104
107
|
* @returns Decompressed Noble EdwardsPoint
|
|
105
108
|
* @throws {Error} If the byte array length is not 32
|
|
106
109
|
* @throws {Error} If the y-coordinate exceeds the field modulus
|
|
107
110
|
* @throws {Error} If the point is not on the curve (no square root exists)
|
|
108
|
-
* @throws {Error} If
|
|
111
|
+
* @throws {Error} If validatePointOnCurve is true and point is not on the curve
|
|
109
112
|
*/
|
|
110
|
-
static bytesToPoint(
|
|
113
|
+
static bytesToPoint(
|
|
114
|
+
bytes: Uint8Array,
|
|
115
|
+
validatePointOnCurve = true,
|
|
116
|
+
): EdwardsPoint {
|
|
111
117
|
if (bytes.length !== 32) {
|
|
112
118
|
throw new Error(
|
|
113
119
|
`Invalid compressed point length: ${bytes.length}, expected 32`,
|
|
@@ -167,25 +173,27 @@ export class BandersnatchCurve {
|
|
|
167
173
|
// Create Noble point from affine coordinates
|
|
168
174
|
const point = Bandersnatch.fromAffine({ x: finalX, y })
|
|
169
175
|
|
|
170
|
-
//
|
|
176
|
+
// Optionally validate point is in prime subgroup as required by bandersnatch-vrf-spec section 2.1:
|
|
171
177
|
// "This function MUST outputs 'INVALID' if the octet-string does not decode
|
|
172
178
|
// to a point on the prime subgroup G"
|
|
173
179
|
// A point is in the prime subgroup if and only if multiplying by the curve order
|
|
174
180
|
// gives the identity point (infinity)
|
|
175
181
|
// Since @noble/curves requires 1 <= scalar < curve.n, we use CURVE_ORDER - 1
|
|
176
182
|
// and then add the point once more: point * CURVE_ORDER = point * (CURVE_ORDER - 1) + point
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
const pointTimesOrder = this.add(pointTimesOrderMinusOne, point)
|
|
183
|
-
const isInPrimeSubgroup = pointTimesOrder.equals(Bandersnatch.ZERO)
|
|
184
|
-
|
|
185
|
-
if (!isInPrimeSubgroup) {
|
|
186
|
-
throw new Error(
|
|
187
|
-
'Point is not in prime subgroup: decoded point is not in G',
|
|
183
|
+
if (validatePointOnCurve) {
|
|
184
|
+
const curveOrderMinusOne = BANDERSNATCH_PARAMS.CURVE_ORDER - 1n
|
|
185
|
+
const pointTimesOrderMinusOne = this.scalarMultiply(
|
|
186
|
+
point,
|
|
187
|
+
curveOrderMinusOne,
|
|
188
188
|
)
|
|
189
|
+
const pointTimesOrder = this.add(pointTimesOrderMinusOne, point)
|
|
190
|
+
const isInPrimeSubgroup = pointTimesOrder.equals(Bandersnatch.ZERO)
|
|
191
|
+
|
|
192
|
+
if (!isInPrimeSubgroup) {
|
|
193
|
+
throw new Error(
|
|
194
|
+
'Point is not in prime subgroup: decoded point is not in G',
|
|
195
|
+
)
|
|
196
|
+
}
|
|
189
197
|
}
|
|
190
198
|
|
|
191
199
|
return point
|