functionalscript 0.8.1 → 0.8.2
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/crypto/secp/module.f.d.ts +10 -7
- package/crypto/secp/module.f.js +32 -12
- package/crypto/secp/test.f.js +4 -5
- package/crypto/sign/module.f.d.ts +17 -4
- package/crypto/sign/module.f.js +141 -47
- package/crypto/sign/test.f.d.ts +11 -1
- package/crypto/sign/test.f.js +631 -1
- package/nanvm-lib/tests/vm/test.f.js +1 -1
- package/package.json +1 -1
- package/path/module.f.d.ts +3 -2
- package/{crypto → types}/prime_field/module.f.d.ts +1 -1
- package/{crypto → types}/prime_field/module.f.js +1 -1
- package/crypto/rfc6979/module.f.d.ts +0 -15
- package/crypto/rfc6979/module.f.js +0 -98
- package/crypto/rfc6979/test.f.d.ts +0 -10
- package/crypto/rfc6979/test.f.js +0 -490
- /package/{crypto → types}/prime_field/test.f.d.ts +0 -0
- /package/{crypto → types}/prime_field/test.f.js +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Equal, Fold, Reduce } from '../../types/function/operator/module.f.ts';
|
|
2
|
-
import { type PrimeField } from '
|
|
2
|
+
import { type PrimeField } from '../../types/prime_field/module.f.ts';
|
|
3
3
|
/**
|
|
4
4
|
* A 2D point represented as a pair of `bigint` values `[x, y]`.
|
|
5
5
|
*/
|
|
@@ -24,6 +24,7 @@ export type Init = {
|
|
|
24
24
|
export type Curve = {
|
|
25
25
|
readonly pf: PrimeField;
|
|
26
26
|
readonly nf: PrimeField;
|
|
27
|
+
readonly g: Point;
|
|
27
28
|
readonly y2: (x: bigint) => bigint;
|
|
28
29
|
readonly y: (x: bigint) => bigint | null;
|
|
29
30
|
readonly neg: (a: Point) => Point;
|
|
@@ -50,27 +51,29 @@ export type Curve = {
|
|
|
50
51
|
* const mulPoint = curveInstance.mul([1n, 1n])(3n); // Multiply a point by 3
|
|
51
52
|
* ```
|
|
52
53
|
*/
|
|
53
|
-
export declare const curve: ({ p, a: [a0, a1], n }: Init) => Curve;
|
|
54
|
+
export declare const curve: ({ p, a: [a0, a1], n, g }: Init) => Curve;
|
|
54
55
|
export declare const eq: Equal<Point>;
|
|
55
56
|
/**
|
|
56
57
|
* https://neuromancer.sk/std/secg/secp192r1
|
|
58
|
+
* NIST P-192
|
|
57
59
|
*/
|
|
58
|
-
export declare const secp192r1:
|
|
60
|
+
export declare const secp192r1: Curve;
|
|
59
61
|
/**
|
|
60
62
|
* https://en.bitcoin.it/wiki/Secp256k1
|
|
61
63
|
* https://neuromancer.sk/std/secg/secp256k1
|
|
62
64
|
*/
|
|
63
|
-
export declare const secp256k1:
|
|
65
|
+
export declare const secp256k1: Curve;
|
|
64
66
|
/**
|
|
65
67
|
* https://neuromancer.sk/std/secg/secp256r1
|
|
68
|
+
* NIST P-256
|
|
66
69
|
*/
|
|
67
|
-
export declare const secp256r1:
|
|
70
|
+
export declare const secp256r1: Curve;
|
|
68
71
|
/**
|
|
69
72
|
* https://neuromancer.sk/std/secg/secp384r1
|
|
70
73
|
*/
|
|
71
|
-
export declare const secp384r1:
|
|
74
|
+
export declare const secp384r1: Curve;
|
|
72
75
|
/**
|
|
73
76
|
* https://neuromancer.sk/std/secg/secp521r1
|
|
74
77
|
*/
|
|
75
|
-
export declare const secp521r1:
|
|
78
|
+
export declare const secp521r1: Curve;
|
|
76
79
|
export {};
|
package/crypto/secp/module.f.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { prime_field, sqrt } from "
|
|
1
|
+
import { prime_field, sqrt } from "../../types/prime_field/module.f.js";
|
|
2
2
|
import { repeat } from "../../types/monoid/module.f.js";
|
|
3
3
|
/**
|
|
4
4
|
* Constructs an elliptic curve with the given initialization parameters.
|
|
@@ -20,7 +20,7 @@ import { repeat } from "../../types/monoid/module.f.js";
|
|
|
20
20
|
* const mulPoint = curveInstance.mul([1n, 1n])(3n); // Multiply a point by 3
|
|
21
21
|
* ```
|
|
22
22
|
*/
|
|
23
|
-
export const curve = ({ p, a: [a0, a1], n }) => {
|
|
23
|
+
export const curve = ({ p, a: [a0, a1], n, g }) => {
|
|
24
24
|
const pf = prime_field(p);
|
|
25
25
|
const { pow2, pow3, sub, add, mul, neg, div } = pf;
|
|
26
26
|
const mul3 = mul(3n);
|
|
@@ -60,6 +60,7 @@ export const curve = ({ p, a: [a0, a1], n }) => {
|
|
|
60
60
|
return {
|
|
61
61
|
pf,
|
|
62
62
|
nf: prime_field(n),
|
|
63
|
+
g,
|
|
63
64
|
y2,
|
|
64
65
|
y: x => sqrt_p(y2(x)),
|
|
65
66
|
neg: p => {
|
|
@@ -83,8 +84,9 @@ export const eq = a => b => {
|
|
|
83
84
|
};
|
|
84
85
|
/**
|
|
85
86
|
* https://neuromancer.sk/std/secg/secp192r1
|
|
87
|
+
* NIST P-192
|
|
86
88
|
*/
|
|
87
|
-
export const secp192r1 = {
|
|
89
|
+
export const secp192r1 = curve({
|
|
88
90
|
p: 0xfffffffffffffffffffffffffffffffeffffffffffffffffn,
|
|
89
91
|
a: [
|
|
90
92
|
0x64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1n,
|
|
@@ -95,12 +97,29 @@ export const secp192r1 = {
|
|
|
95
97
|
0x07192b95ffc8da78631011ed6b24cdd573f977a11e794811n
|
|
96
98
|
],
|
|
97
99
|
n: 0xffffffffffffffffffffffff99def836146bc9b1b4d22831n,
|
|
98
|
-
};
|
|
100
|
+
});
|
|
101
|
+
// The curve doesn't have a simple square root function.
|
|
102
|
+
// /**
|
|
103
|
+
// * https://std.neuromancer.sk/nist/P-224
|
|
104
|
+
// * NIST P-224
|
|
105
|
+
// */
|
|
106
|
+
// export const secp224r1: Curve = curve({
|
|
107
|
+
// p: 0xffffffff_ffffffff_ffffffff_ffffffff_00000000_00000000_00000001n,
|
|
108
|
+
// a: [
|
|
109
|
+
// 0xb4050a85_0c04b3ab_f5413256_5044b0b7_d7bfd8ba_270b3943_2355ffb4n,
|
|
110
|
+
// 0xffffffff_ffffffff_ffffffff_fffffffe_ffffffff_ffffffff_fffffffen,
|
|
111
|
+
// ],
|
|
112
|
+
// g: [
|
|
113
|
+
// 0xb70e0cbd_6bb4bf7f_321390b9_4a03c1d3_56c21122_343280d6_115c1d21n,
|
|
114
|
+
// 0xbd376388_b5f723fb_4c22dfe6_cd4375a0_5a074764_44d58199_85007e34n,
|
|
115
|
+
// ],
|
|
116
|
+
// n: 0xffffffff_ffffffff_ffffffff_ffff16a2_e0b8f03e_13dd2945_5c5c2a3dn,
|
|
117
|
+
// })
|
|
99
118
|
/**
|
|
100
119
|
* https://en.bitcoin.it/wiki/Secp256k1
|
|
101
120
|
* https://neuromancer.sk/std/secg/secp256k1
|
|
102
121
|
*/
|
|
103
|
-
export const secp256k1 = {
|
|
122
|
+
export const secp256k1 = curve({
|
|
104
123
|
p: 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2fn,
|
|
105
124
|
a: [7n, 0n],
|
|
106
125
|
g: [
|
|
@@ -108,11 +127,12 @@ export const secp256k1 = {
|
|
|
108
127
|
0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8n
|
|
109
128
|
],
|
|
110
129
|
n: 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141n,
|
|
111
|
-
};
|
|
130
|
+
});
|
|
112
131
|
/**
|
|
113
132
|
* https://neuromancer.sk/std/secg/secp256r1
|
|
133
|
+
* NIST P-256
|
|
114
134
|
*/
|
|
115
|
-
export const secp256r1 = {
|
|
135
|
+
export const secp256r1 = curve({
|
|
116
136
|
p: 0xffffffff00000001000000000000000000000000ffffffffffffffffffffffffn,
|
|
117
137
|
a: [
|
|
118
138
|
0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604bn, //< b
|
|
@@ -123,11 +143,11 @@ export const secp256r1 = {
|
|
|
123
143
|
0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5n, //< y
|
|
124
144
|
],
|
|
125
145
|
n: 0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551n,
|
|
126
|
-
};
|
|
146
|
+
});
|
|
127
147
|
/**
|
|
128
148
|
* https://neuromancer.sk/std/secg/secp384r1
|
|
129
149
|
*/
|
|
130
|
-
export const secp384r1 = {
|
|
150
|
+
export const secp384r1 = curve({
|
|
131
151
|
p: 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000ffffffffn,
|
|
132
152
|
a: [
|
|
133
153
|
0xb3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875ac656398d8a2ed19d2a85c8edd3ec2aefn, //< b
|
|
@@ -138,11 +158,11 @@ export const secp384r1 = {
|
|
|
138
158
|
0x3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b1ce1d7e819d7a431d7c90ea0e5fn, //< y
|
|
139
159
|
],
|
|
140
160
|
n: 0xffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52973n,
|
|
141
|
-
};
|
|
161
|
+
});
|
|
142
162
|
/**
|
|
143
163
|
* https://neuromancer.sk/std/secg/secp521r1
|
|
144
164
|
*/
|
|
145
|
-
export const secp521r1 = {
|
|
165
|
+
export const secp521r1 = curve({
|
|
146
166
|
p: 0x01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffn,
|
|
147
167
|
a: [
|
|
148
168
|
0x0051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00n, //< b
|
|
@@ -153,4 +173,4 @@ export const secp521r1 = {
|
|
|
153
173
|
0x011839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650n,
|
|
154
174
|
],
|
|
155
175
|
n: 0x01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409n
|
|
156
|
-
};
|
|
176
|
+
});
|
package/crypto/secp/test.f.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { prime_field } from "
|
|
1
|
+
import { prime_field } from "../../types/prime_field/module.f.js";
|
|
2
2
|
import { curve, secp256k1, secp192r1, secp256r1, eq, secp384r1, secp521r1 } from "./module.f.js";
|
|
3
3
|
const poker = (param) => () => {
|
|
4
4
|
// (c ^ x) ^ y = c ^ (x * y)
|
|
5
5
|
// c ^ ((x * y) * (1/x * 1/y)) = c
|
|
6
|
-
const { g, n } = param
|
|
7
|
-
const { mul, y } =
|
|
6
|
+
// const { g, n } = param
|
|
7
|
+
const { mul, y, nf: { p: n } } = param;
|
|
8
8
|
const f = (m) => (pList) => pList.map(mul(m));
|
|
9
9
|
//
|
|
10
10
|
const pf = prime_field(n);
|
|
@@ -69,8 +69,7 @@ export default {
|
|
|
69
69
|
},
|
|
70
70
|
test: () => {
|
|
71
71
|
const test_curve = c => {
|
|
72
|
-
const { g } = c;
|
|
73
|
-
const { mul, neg, pf: { abs }, y: yf, nf: { p: n } } = curve(c);
|
|
72
|
+
const { mul, neg, pf: { abs }, y: yf, nf: { p: n }, g } = c;
|
|
74
73
|
const point_check = (p) => {
|
|
75
74
|
if (p === null) {
|
|
76
75
|
throw 'p === null';
|
|
@@ -1,5 +1,18 @@
|
|
|
1
|
+
import type { Array2 } from '../../types/array/module.f.ts';
|
|
1
2
|
import { type Vec } from '../../types/bit_vec/module.f.ts';
|
|
2
|
-
import {
|
|
3
|
-
import type
|
|
4
|
-
export
|
|
5
|
-
|
|
3
|
+
import type { Curve } from '../secp/module.f.ts';
|
|
4
|
+
import { type Sha2 } from '../sha2/module.f.ts';
|
|
5
|
+
export type All = {
|
|
6
|
+
readonly q: bigint;
|
|
7
|
+
readonly qlen: bigint;
|
|
8
|
+
readonly bits2int: (b: Vec) => bigint;
|
|
9
|
+
readonly int2octets: (x: bigint) => Vec;
|
|
10
|
+
readonly bits2octets: (b: Vec) => Vec;
|
|
11
|
+
};
|
|
12
|
+
export declare const all: (q: bigint) => All;
|
|
13
|
+
export declare const fromCurve: (c: Curve) => All;
|
|
14
|
+
export declare const concat: (...x: readonly Vec[]) => Vec;
|
|
15
|
+
export declare const computeK: (_: All) => (_: Sha2) => (x: bigint) => (m: Vec) => bigint;
|
|
16
|
+
type Signature = Array2<bigint>;
|
|
17
|
+
export declare const sign: (c: Curve) => (hf: Sha2) => (x: bigint) => (m: Vec) => Signature;
|
|
18
|
+
export {};
|
package/crypto/sign/module.f.js
CHANGED
|
@@ -1,54 +1,148 @@
|
|
|
1
|
-
import { bitLength } from "../../types/bigint/module.f.js";
|
|
2
|
-
import { listToVec, msb,
|
|
1
|
+
import { bitLength, divUp, roundUp } from "../../types/bigint/module.f.js";
|
|
2
|
+
import { empty, length, listToVec, msb, repeat, unpack, vec, vec8 } from "../../types/bit_vec/module.f.js";
|
|
3
3
|
import { hmac } from "../hmac/module.f.js";
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
4
|
+
import { computeSync } from "../sha2/module.f.js";
|
|
5
|
+
// qlen to rlen
|
|
6
|
+
const roundUp8 = roundUp(8n);
|
|
7
|
+
const divUp8 = divUp(8n);
|
|
8
|
+
export const all = (q) => {
|
|
9
|
+
const qlen = bitLength(q);
|
|
10
|
+
const bits2int = (b) => {
|
|
11
|
+
const { length, uint } = unpack(b);
|
|
12
|
+
const diff = length - qlen;
|
|
13
|
+
return diff > 0n ? uint >> diff : uint;
|
|
14
|
+
};
|
|
15
|
+
const int2octets = vec(roundUp8(qlen));
|
|
16
|
+
return {
|
|
17
|
+
q,
|
|
18
|
+
qlen,
|
|
19
|
+
bits2int,
|
|
20
|
+
int2octets,
|
|
21
|
+
// since z2 < 2*q, we can use simple mod with `z1 < q ? z1 : z1 - q`
|
|
22
|
+
bits2octets: b => int2octets(bits2int(b) % q),
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
export const fromCurve = (c) => all(c.nf.p);
|
|
26
|
+
const x01 = vec8(0x01n);
|
|
27
|
+
const x00 = vec8(0x00n);
|
|
28
|
+
const ltov = listToVec(msb);
|
|
29
|
+
export const concat = (...x) => ltov(x);
|
|
30
|
+
export const computeK = ({ q, bits2int, qlen, int2octets, bits2octets }) => hf => {
|
|
31
|
+
// TODO: Look at https://www.rfc-editor.org/rfc/rfc6979#section-3.3 to reformulate
|
|
32
|
+
// it using `HMAC_DRBG`.
|
|
33
|
+
const hmacf = hmac(hf);
|
|
34
|
+
// b. Set:
|
|
35
|
+
// V = 0x01 0x01 0x01 ... 0x01
|
|
36
|
+
// such that the length of V, in bits, is equal to 8*ceil(hlen/8).
|
|
37
|
+
// For instance, on an octet-based system, if H is SHA-256, then V
|
|
38
|
+
// is set to a sequence of 32 octets of value 1. Note that in this
|
|
39
|
+
// step and all subsequent steps, we use the same H function as the
|
|
40
|
+
// one used in step 'a' to process the input message; this choice
|
|
41
|
+
// will be discussed in more detail in Section 3.6.
|
|
42
|
+
const rep = repeat(divUp8(hf.hashLength));
|
|
43
|
+
const v0 = rep(x01);
|
|
44
|
+
// c. Set:
|
|
45
|
+
// K = 0x00 0x00 0x00 ... 0x00
|
|
46
|
+
// such that the length of K, in bits, is equal to 8*ceil(hlen/8).
|
|
47
|
+
const k0 = rep(x00);
|
|
48
|
+
//
|
|
49
|
+
return x => m => {
|
|
22
50
|
let v = v0;
|
|
23
|
-
k =
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
51
|
+
let k = k0;
|
|
52
|
+
// a. Process m through the hash function H, yielding:
|
|
53
|
+
// h1 = H(m)
|
|
54
|
+
// (h1 is a sequence of hlen bits).
|
|
55
|
+
const h1 = computeSync(hf)([m]);
|
|
56
|
+
// d. Set:
|
|
57
|
+
// K = HMAC_K(V || 0x00 || int2octets(x) || bits2octets(h1))
|
|
58
|
+
// where '||' denotes concatenation.
|
|
59
|
+
const xh1 = concat(int2octets(x), bits2octets(h1));
|
|
60
|
+
k = hmacf(k)(concat(v, x00, xh1));
|
|
61
|
+
// e. Set:
|
|
62
|
+
// V = HMAC_K(V)
|
|
63
|
+
v = hmacf(k)(v);
|
|
64
|
+
// f. Set:
|
|
65
|
+
// K = HMAC_K(V || 0x01 || int2octets(x) || bits2octets(h1))
|
|
66
|
+
k = hmacf(k)(concat(v, x01, xh1));
|
|
67
|
+
// g. Set:
|
|
68
|
+
// V = HMAC_K(V)
|
|
69
|
+
v = hmacf(k)(v);
|
|
70
|
+
// h. Apply the following algorithm until a proper value is for `k`:
|
|
71
|
+
while (true) {
|
|
72
|
+
// h. Apply the following algorithm until a proper value is for `k`:
|
|
73
|
+
// 1. Set `T` to the empty sequence, so `tlen = 0`.
|
|
74
|
+
let t = empty;
|
|
75
|
+
// 2. while `tlen < qlen` do:
|
|
76
|
+
// - `V = HMAC_K(V)`
|
|
77
|
+
// - `T = T || V`
|
|
78
|
+
// Possible optimizations:
|
|
79
|
+
// - precompute number of iterations
|
|
80
|
+
// - `qlen` can't be 0, so we can avoid the first check and
|
|
81
|
+
// first concatenation.
|
|
82
|
+
while (length(t) < qlen) {
|
|
83
|
+
v = hmacf(k)(v);
|
|
84
|
+
t = concat(t, v);
|
|
85
|
+
}
|
|
86
|
+
// 3. Compute `k = bits2int(T)`. If `k` is not in `[1, q-1]` or `kG = 0` then
|
|
87
|
+
// - `K = HMAC_K(V || 0x00)`
|
|
88
|
+
// - `V = HMAC_K(V)`
|
|
89
|
+
// and loop (try to generate a new `T`, and so on). Return to step `1`.
|
|
90
|
+
const result = bits2int(t);
|
|
91
|
+
if (0n < result && result < q) {
|
|
92
|
+
return result;
|
|
93
|
+
}
|
|
94
|
+
k = hmacf(k)(concat(v, x00));
|
|
95
|
+
v = hmacf(k)(v);
|
|
96
|
+
}
|
|
28
97
|
};
|
|
29
98
|
};
|
|
30
|
-
export const
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
99
|
+
export const sign = (c) => (hf) => (x) => (m) => {
|
|
100
|
+
// 2.4 Signature Generation
|
|
101
|
+
const { nf: { p: q, div }, g } = c;
|
|
102
|
+
const a = all(q);
|
|
103
|
+
const { bits2int } = a;
|
|
104
|
+
// The following steps are then applied:
|
|
105
|
+
//
|
|
106
|
+
// 1. H(m) is transformed into an integer modulo q using the bits2int
|
|
107
|
+
// transform and an extra modular reduction:
|
|
108
|
+
//
|
|
109
|
+
// h = bits2int(H(m)) mod q
|
|
110
|
+
//
|
|
111
|
+
// As was noted in the description of bits2octets, the extra modular
|
|
112
|
+
// reduction is no more than a conditional subtraction.
|
|
113
|
+
const hm = computeSync(hf)([m]);
|
|
114
|
+
const h = bits2int(hm) % q;
|
|
115
|
+
// 2. A random value modulo q, dubbed k, is generated. That value
|
|
116
|
+
// shall not be 0; hence, it lies in the [1, q-1] range. Most of
|
|
117
|
+
// the remainder of this document will revolve around the process
|
|
118
|
+
// used to generate k. In plain DSA or ECDSA, k should be selected
|
|
119
|
+
// through a random selection that chooses a value among the q-1
|
|
120
|
+
// possible values with uniform probability.
|
|
121
|
+
const k = computeK(a)(hf)(x)(m);
|
|
122
|
+
// 3. A value r (modulo q) is computed from k and the key parameters:
|
|
123
|
+
//
|
|
124
|
+
// * For ECDSA: the point kG is computed; its X coordinate (a
|
|
125
|
+
// member of the field over which E is defined) is converted to
|
|
126
|
+
// an integer, which is reduced modulo q, yielding r.
|
|
127
|
+
//
|
|
128
|
+
// If r turns out to be zero, a new k should be selected and r
|
|
129
|
+
// computed again (this is an utterly improbable occurrence).
|
|
130
|
+
const rxy = c.mul(k)(g);
|
|
131
|
+
// TODO: implement the loop. `computeK` should either
|
|
132
|
+
// - accept a state (current `k`).
|
|
133
|
+
// - accept a `is_valid` function.
|
|
134
|
+
if (rxy === null) {
|
|
135
|
+
throw 'rxy === null';
|
|
34
136
|
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
//
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
//
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
const r = rp === null ? 0n : rp[0];
|
|
46
|
-
// `s = ((z + r * d) / k)`.
|
|
47
|
-
const d = uint(privateKey);
|
|
48
|
-
const z = uint(messageHash);
|
|
49
|
-
const rd = pf.mul(r)(d);
|
|
50
|
-
const zrd = pf.add(z)(rd);
|
|
51
|
-
const kn1 = pf.reciprocal(k);
|
|
52
|
-
const s = pf.mul(zrd)(kn1);
|
|
137
|
+
const [r] = rxy;
|
|
138
|
+
// 4. The value s (modulo q) is computed:
|
|
139
|
+
//
|
|
140
|
+
// s = (h+x*r)/k mod q
|
|
141
|
+
//
|
|
142
|
+
// The pair (r, s) is the signature. How a signature is to be
|
|
143
|
+
// encoded is not covered by the DSA and ECDSA standards themselves;
|
|
144
|
+
// a common way is to use a DER-encoded ASN.1 structure (a SEQUENCE
|
|
145
|
+
// of two INTEGERs, for r and s, in that order).
|
|
146
|
+
const s = div(h + x * r)(k);
|
|
53
147
|
return [r, s];
|
|
54
148
|
};
|
package/crypto/sign/test.f.d.ts
CHANGED
|
@@ -1,2 +1,12 @@
|
|
|
1
|
-
declare const _default: {
|
|
1
|
+
declare const _default: {
|
|
2
|
+
bits2int: () => void;
|
|
3
|
+
int2octets: () => void;
|
|
4
|
+
bit2octets: () => void;
|
|
5
|
+
k: () => void;
|
|
6
|
+
computeK: () => void;
|
|
7
|
+
investigate: () => void;
|
|
8
|
+
kk: () => void;
|
|
9
|
+
a2: () => void;
|
|
10
|
+
a2s: () => void;
|
|
11
|
+
};
|
|
2
12
|
export default _default;
|