-
Notifications
You must be signed in to change notification settings - Fork 0
/
noble-curves.ts
86 lines (78 loc) · 2.54 KB
/
noble-curves.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
import { hmac } from '@noble/hashes/hmac';
import { sha256 } from '@noble/hashes/sha256';
import { bytesToNumberBE, concatBytes } from '@noble/curves/abstract/utils';
import { createHmacDrbg } from '@noble/curves/abstract/utils';
import { secp256k1 } from '@noble/curves/secp256k1';
import { invert } from '@noble/curves/abstract/modular';
const { ProjectivePoint: Point, CURVE } = secp256k1;
// Rest of the implementation remains the same
const drbg = createHmacDrbg(
32,
32,
(key: Uint8Array, ...messages: Uint8Array[]) => hmac(sha256, key, concatBytes(...messages))
);
const test_vectors = [
{
privateKey: new Uint8Array(
Buffer.from(
"0000000000000000000000000000000000000000000000000000000000000001",
"hex"
)
),
message: new Uint8Array(
Buffer.from(
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
"hex"
)
),
},
{
privateKey: new Uint8Array(
Buffer.from(
"fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140",
"hex"
)
),
message: new Uint8Array(
Buffer.from(
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
"hex"
)
),
},
{
privateKey: new Uint8Array(
Buffer.from(
"fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140",
"hex"
)
),
message: new Uint8Array(
Buffer.from(
"fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141",
"hex"
)
),
},
];
for (const test of test_vectors) {
console.log("\nTest vector:", test);
// The message here is not reduced before passing it to the hmac function.
// This generates the same k and R compared to other implementations.
// Then why the signature is different from other implementations when using the sign function?
// It turns out in the nobles curves implementation the message is reduced mod curve order before this step
// explaining the difference.
const k = drbg(concatBytes(test.privateKey, test.message), (bytes) => {
const num = bytesToNumberBE(bytes);
if (num <= 0n || num >= CURVE.n) return;
return num;
}) as bigint;
console.log('k:', k.toString(16));
const kInv = invert(k, CURVE.n);
console.log('k_inv:', kInv.toString(16));
const R = Point.BASE.multiply(k);
console.log('Rx:', R.toAffine().x.toString(16));
const signature = secp256k1.sign(test.message, test.privateKey);
console.log('r:', signature.r.toString(16));
console.log('s:', signature.s.toString(16));
}