Skip to content

Commit aba10c3

Browse files
Merge pull request #396 from bsv-blockchain/r1
Implement secp256r1
2 parents 31d540b + 55c4d99 commit aba10c3

File tree

7 files changed

+605
-417
lines changed

7 files changed

+605
-417
lines changed

CHANGELOG.md

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ All notable changes to this project will be documented in this file. The format
44

55
## Table of Contents
66

7-
- [Unreleased](#unreleased)"
7+
- [Unreleased](#unreleased)
8+
- [1.9.14 - 2025-12-01](#1914---2025-12-01)
89
- [1.9.13 - 2025-12-01](#1913---2025-12-01)
910
- [1.9.12 - 2025-12-01](#1912---2025-12-01)
1011
- [1.9.11 - 2025-11-24](#1911---2025-11-24)
@@ -183,21 +184,31 @@ All notable changes to this project will be documented in this file. The format
183184
### Fixed
184185

185186
### Security
187+
188+
### [1.9.14] - 2025-12-01
189+
190+
### Added
191+
192+
- Added a standalone secp256r1 (P-256) BigInt implementation with ECDSA signing, verification, and tests.
193+
186194
---
195+
187196
### [1.9.13] - 2025-12-01
188197

189198
### Added
190199

191200
- Changed the toArray function to throw on invalid base64 strings.
192201

193202
---
203+
194204
### [1.9.12] - 2025-12-01
195205

196206
### Added
197207

198208
- Added decryption validation to SymmetricKey.
199209

200210
---
211+
201212
### [1.9.11] - 2025-11-24
202213

203214
### Removed
@@ -206,6 +217,7 @@ All notable changes to this project will be documented in this file. The format
206217

207218

208219
---
220+
209221
### [1.9.10] - 2025-11-17
210222

211223
### Added

docs/reference/primitives.md

Lines changed: 152 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,11 @@ Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](
4848
| [BigNumber](#class-bignumber) | [Polynomial](#class-polynomial) | [SHA512](#class-sha512) |
4949
| [Curve](#class-curve) | [PrivateKey](#class-privatekey) | [SHA512HMAC](#class-sha512hmac) |
5050
| [DRBG](#class-drbg) | [PublicKey](#class-publickey) | [Schnorr](#class-schnorr) |
51-
| [JacobianPoint](#class-jacobianpoint) | [RIPEMD160](#class-ripemd160) | [Signature](#class-signature) |
52-
| [K256](#class-k256) | [Reader](#class-reader) | [SymmetricKey](#class-symmetrickey) |
53-
| [KeyShares](#class-keyshares) | [ReductionContext](#class-reductioncontext) | [TransactionSignature](#class-transactionsignature) |
54-
| [Mersenne](#class-mersenne) | [SHA1](#class-sha1) | [Writer](#class-writer) |
55-
| [MontgomoryMethod](#class-montgomorymethod) | [SHA1HMAC](#class-sha1hmac) | |
51+
| [JacobianPoint](#class-jacobianpoint) | [RIPEMD160](#class-ripemd160) | [Secp256r1](#class-secp256r1) |
52+
| [K256](#class-k256) | [Reader](#class-reader) | [Signature](#class-signature) |
53+
| [KeyShares](#class-keyshares) | [ReductionContext](#class-reductioncontext) | [SymmetricKey](#class-symmetrickey) |
54+
| [Mersenne](#class-mersenne) | [SHA1](#class-sha1) | [TransactionSignature](#class-transactionsignature) |
55+
| [MontgomoryMethod](#class-montgomorymethod) | [SHA1HMAC](#class-sha1hmac) | [Writer](#class-writer) |
5656
| [Point](#class-point) | [SHA256](#class-sha256) | |
5757

5858
Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types), [Enums](#enums), [Variables](#variables)
@@ -4320,6 +4320,141 @@ Argument Details
43204320
43214321
Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types), [Enums](#enums), [Variables](#variables)
43224322
4323+
---
4324+
### Class: Secp256r1
4325+
4326+
Pure BigInt implementation of the NIST P-256 (secp256r1) curve with ECDSA sign/verify.
4327+
4328+
This class is standalone (no dependency on the existing secp256k1 primitives) and exposes
4329+
key generation, point encoding/decoding, scalar multiplication, and SHA-256 based ECDSA.
4330+
4331+
```ts
4332+
export default class Secp256r1 {
4333+
readonly p = P;
4334+
readonly n = N;
4335+
readonly a = A;
4336+
readonly b = B;
4337+
readonly g = G;
4338+
pointFromAffine(x: bigint, y: bigint): P256Point
4339+
pointFromHex(hex: string): P256Point
4340+
pointToHex(p: P256Point, compressed = false): string
4341+
add(p1: P256Point, p2: P256Point): P256Point
4342+
multiply(point: P256Point, scalar: bigint): P256Point
4343+
multiplyBase(scalar: bigint): P256Point
4344+
isOnCurve(p: P256Point): boolean
4345+
generatePrivateKeyHex(): string
4346+
publicKeyFromPrivate(privateKey: string | bigint): P256Point
4347+
sign(message: ByteSource, privateKey: string | bigint, opts: {
4348+
prehashed?: boolean;
4349+
nonce?: bigint;
4350+
} = {}): {
4351+
r: string;
4352+
s: string;
4353+
}
4354+
verify(message: ByteSource, signature: {
4355+
r: string | bigint;
4356+
s: string | bigint;
4357+
}, publicKey: P256Point | string, opts: {
4358+
prehashed?: boolean;
4359+
} = {}): boolean
4360+
}
4361+
```
4362+
4363+
See also: [P256Point](./primitives.md#type-p256point), [multiply](./primitives.md#variable-multiply), [sign](./compat.md#variable-sign), [verify](./compat.md#variable-verify)
4364+
4365+
#### Method add
4366+
4367+
Add two points (handles infinity).
4368+
4369+
```ts
4370+
add(p1: P256Point, p2: P256Point): P256Point
4371+
```
4372+
See also: [P256Point](./primitives.md#type-p256point)
4373+
4374+
#### Method generatePrivateKeyHex
4375+
4376+
Generate a new random private key as 32-byte hex.
4377+
4378+
```ts
4379+
generatePrivateKeyHex(): string
4380+
```
4381+
4382+
#### Method isOnCurve
4383+
4384+
Check if a point lies on the curve (including infinity).
4385+
4386+
```ts
4387+
isOnCurve(p: P256Point): boolean
4388+
```
4389+
See also: [P256Point](./primitives.md#type-p256point)
4390+
4391+
#### Method multiply
4392+
4393+
Scalar multiply an arbitrary point using double-and-add.
4394+
4395+
```ts
4396+
multiply(point: P256Point, scalar: bigint): P256Point
4397+
```
4398+
See also: [P256Point](./primitives.md#type-p256point)
4399+
4400+
#### Method multiplyBase
4401+
4402+
Scalar multiply the base point.
4403+
4404+
```ts
4405+
multiplyBase(scalar: bigint): P256Point
4406+
```
4407+
See also: [P256Point](./primitives.md#type-p256point)
4408+
4409+
#### Method pointFromHex
4410+
4411+
Decode a point from compressed or uncompressed hex.
4412+
4413+
```ts
4414+
pointFromHex(hex: string): P256Point
4415+
```
4416+
See also: [P256Point](./primitives.md#type-p256point)
4417+
4418+
#### Method pointToHex
4419+
4420+
Encode a point to compressed or uncompressed hex. Infinity is encoded as `00`.
4421+
4422+
```ts
4423+
pointToHex(p: P256Point, compressed = false): string
4424+
```
4425+
See also: [P256Point](./primitives.md#type-p256point)
4426+
4427+
#### Method sign
4428+
4429+
Create an ECDSA signature over a message. Uses SHA-256 unless `prehashed` is true.
4430+
Returns low-s normalized signature hex parts.
4431+
4432+
```ts
4433+
sign(message: ByteSource, privateKey: string | bigint, opts: {
4434+
prehashed?: boolean;
4435+
nonce?: bigint;
4436+
} = {}): {
4437+
r: string;
4438+
s: string;
4439+
}
4440+
```
4441+
4442+
#### Method verify
4443+
4444+
Verify an ECDSA signature against a message and public key.
4445+
4446+
```ts
4447+
verify(message: ByteSource, signature: {
4448+
r: string | bigint;
4449+
s: string | bigint;
4450+
}, publicKey: P256Point | string, opts: {
4451+
prehashed?: boolean;
4452+
} = {}): boolean
4453+
```
4454+
See also: [P256Point](./primitives.md#type-p256point)
4455+
4456+
Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types), [Enums](#enums), [Variables](#variables)
4457+
43234458
---
43244459
### Class: Signature
43254460
@@ -4994,6 +5129,18 @@ Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](
49945129
---
49955130
## Types
49965131

5132+
### Type: P256Point
5133+
5134+
```ts
5135+
export type P256Point = {
5136+
x: bigint;
5137+
y: bigint;
5138+
} | null
5139+
```
5140+
5141+
Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types), [Enums](#enums), [Variables](#variables)
5142+
5143+
---
49975144
## Enums
49985145
49995146
## Variables

0 commit comments

Comments
 (0)