Skip to content

Commit 3b5cb87

Browse files
authored
Merge pull request #62 from ethereum/bugfixes
Bugfixes
2 parents 92f71f8 + 94f46e4 commit 3b5cb87

File tree

7 files changed

+132
-109
lines changed

7 files changed

+132
-109
lines changed

Diff for: package.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@
2424
"*.d.ts"
2525
],
2626
"dependencies": {
27-
"@noble/hashes": "1.1.5",
27+
"@noble/hashes": "1.2.0",
2828
"@noble/secp256k1": "1.7.1",
29-
"@scure/bip32": "1.1.1",
30-
"@scure/bip39": "1.1.0"
29+
"@scure/bip32": "1.1.5",
30+
"@scure/bip39": "1.1.1"
3131
},
3232
"browser": {
3333
"crypto": false

Diff for: src/aes.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,9 @@ async function getBrowserKey(
4141
true,
4242
["encrypt", "decrypt"]
4343
);
44-
return [wKey, { name: `aes-${keyMode}`, iv, counter: iv, length: 64 }];
44+
// node.js uses whole 128 bit as a counter, without nonce, instead of 64 bit
45+
// recommended by NIST SP800-38A
46+
return [wKey, { name: `aes-${keyMode}`, iv, counter: iv, length: 128 }];
4547
}
4648

4749
export async function encrypt(

Diff for: src/secp256k1-compat.ts

+6-2
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ export function ecdsaSign(
112112
}
113113
const [signature, recid] = secp.signSync(msgHash, privateKey, {
114114
recovered: true,
115-
der: false
115+
der: false,
116116
});
117117
return { signature: output(out, 64, signature), recid };
118118
}
@@ -214,8 +214,12 @@ export function publicKeyCombine(
214214
}
215215
assertBool(compressed);
216216
const combined = publicKeys
217-
.map(pub => secp.Point.fromHex(pub))
217+
.map((pub) => secp.Point.fromHex(pub))
218218
.reduce((res, curr) => res.add(curr), secp.Point.ZERO);
219+
// Prohibit returning ZERO point
220+
if (combined.equals(secp.Point.ZERO)) {
221+
throw new Error("Combined result must not be zero");
222+
}
219223
return output(out, compressed ? 33 : 65, combined.toRawBytes(compressed));
220224
}
221225

Diff for: test/test-vectors/aes.ts

+67-28
Original file line numberDiff line numberDiff line change
@@ -7,98 +7,89 @@ const TEST_VECTORS = [
77
mode: "aes-128-ctr",
88
key: "2b7e151628aed2a6abf7158809cf4f3c",
99
iv: "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff",
10-
msg:
11-
"6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710",
10+
msg: "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710",
1211
cypherText:
1312
"874d6191b620e3261bef6864990db6ce9806f66b7970fdff8617187bb9fffdff5ae4df3edbd5d35e5b4f09020db03eab1e031dda2fbe03d1792170a0f3009cee",
14-
pkcs7PaddingEnabled: false
13+
pkcs7PaddingEnabled: false,
1514
},
1615
// CTR uses no padding, so we test that here
1716
{
1817
mode: "aes-128-ctr",
1918
key: "2b7e151628aed2a6abf7158809cf4f3c",
2019
iv: "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff",
21-
msg:
22-
"6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710",
20+
msg: "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710",
2321
cypherText:
2422
"874d6191b620e3261bef6864990db6ce9806f66b7970fdff8617187bb9fffdff5ae4df3edbd5d35e5b4f09020db03eab1e031dda2fbe03d1792170a0f3009cee",
25-
pkcs7PaddingEnabled: true
23+
pkcs7PaddingEnabled: true,
2624
},
2725
// Same as the previous one, but with default params
2826
{
2927
mode: undefined,
3028
key: "2b7e151628aed2a6abf7158809cf4f3c",
3129
iv: "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff",
32-
msg:
33-
"6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710",
30+
msg: "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710",
3431
cypherText:
3532
"874d6191b620e3261bef6864990db6ce9806f66b7970fdff8617187bb9fffdff5ae4df3edbd5d35e5b4f09020db03eab1e031dda2fbe03d1792170a0f3009cee",
36-
pkcs7PaddingEnabled: undefined
33+
pkcs7PaddingEnabled: undefined,
3734
},
3835
// CBC uses padding, but the NIST test vectors don't
3936
{
4037
mode: "aes-128-cbc",
4138
key: "2b7e151628aed2a6abf7158809cf4f3c",
4239
iv: "000102030405060708090a0b0c0d0e0f",
43-
msg:
44-
"6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710",
40+
msg: "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710",
4541
cypherText:
4642
"7649abac8119b246cee98e9b12e9197d5086cb9b507219ee95db113a917678b273bed6b8e3c1743b7116e69e222295163ff1caa1681fac09120eca307586e1a7",
47-
pkcs7PaddingEnabled: false
43+
pkcs7PaddingEnabled: false,
4844
},
4945
// We test that the padding is in fact PKCS#7 by first entrypting with its
5046
// corresponding padding adding manually, and then with automatic padding
5147
{
5248
mode: "aes-128-cbc",
5349
key: "2b7e151628aed2a6abf7158809cf4f3c",
5450
iv: "000102030405060708090a0b0c0d0e0f",
55-
msg:
56-
"6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c371010101010101010101010101010101010",
51+
msg: "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c371010101010101010101010101010101010",
5752
cypherText:
5853
"7649abac8119b246cee98e9b12e9197d5086cb9b507219ee95db113a917678b273bed6b8e3c1743b7116e69e222295163ff1caa1681fac09120eca307586e1a78cb82807230e1321d3fae00d18cc2012",
59-
pkcs7PaddingEnabled: false
54+
pkcs7PaddingEnabled: false,
6055
},
6156
{
6257
mode: "aes-128-cbc",
6358
key: "2b7e151628aed2a6abf7158809cf4f3c",
6459
iv: "000102030405060708090a0b0c0d0e0f",
65-
msg:
66-
"6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710",
60+
msg: "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710",
6761
cypherText:
6862
"7649abac8119b246cee98e9b12e9197d5086cb9b507219ee95db113a917678b273bed6b8e3c1743b7116e69e222295163ff1caa1681fac09120eca307586e1a78cb82807230e1321d3fae00d18cc2012",
69-
pkcs7PaddingEnabled: true
63+
pkcs7PaddingEnabled: true,
7064
},
7165
// Same applies for aes-256-cbc
7266
{
7367
mode: "aes-256-cbc",
7468
key: "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4",
7569
iv: "000102030405060708090a0b0c0d0e0f",
76-
msg:
77-
"6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710",
70+
msg: "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710",
7871
cypherText:
7972
"f58c4c04d6e5f1ba779eabfb5f7bfbd69cfc4e967edb808d679f777bc6702c7d39f23369a9d9bacfa530e26304231461b2eb05e2c39be9fcda6c19078c6a9d1b",
80-
pkcs7PaddingEnabled: false
73+
pkcs7PaddingEnabled: false,
8174
},
8275
{
8376
mode: "aes-256-cbc",
8477
key: "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4",
8578
iv: "000102030405060708090a0b0c0d0e0f",
86-
msg:
87-
"6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c371010101010101010101010101010101010",
79+
msg: "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c371010101010101010101010101010101010",
8880
cypherText:
8981
"f58c4c04d6e5f1ba779eabfb5f7bfbd69cfc4e967edb808d679f777bc6702c7d39f23369a9d9bacfa530e26304231461b2eb05e2c39be9fcda6c19078c6a9d1b3f461796d6b0d6b2e0c2a72b4d80e644",
90-
pkcs7PaddingEnabled: false
82+
pkcs7PaddingEnabled: false,
9183
},
9284
{
9385
mode: "aes-256-cbc",
9486
key: "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4",
9587
iv: "000102030405060708090a0b0c0d0e0f",
96-
msg:
97-
"6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710",
88+
msg: "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710",
9889
cypherText:
9990
"f58c4c04d6e5f1ba779eabfb5f7bfbd69cfc4e967edb808d679f777bc6702c7d39f23369a9d9bacfa530e26304231461b2eb05e2c39be9fcda6c19078c6a9d1b3f461796d6b0d6b2e0c2a72b4d80e644",
100-
pkcs7PaddingEnabled: true
101-
}
91+
pkcs7PaddingEnabled: true,
92+
},
10293
];
10394

10495
describe("aes", () => {
@@ -151,4 +142,52 @@ describe("aes", () => {
151142
)
152143
);
153144
});
145+
146+
it("aes-ctr bug (browser/node result mismatch)", async () => {
147+
// NOTE: full 0xff iv causes difference on counter overflow in CTR mode
148+
const iv = "ffffffffffffffffffffffffffffffff";
149+
const vectors = [
150+
{
151+
msg: "efca4cdd31923b50f4214af5d2ae10e7ac45a5019e9431cc195482d707485378",
152+
key: "ccc0b35ea59c51a1e45af00502966237",
153+
iv,
154+
mode: "aes-128-ctr",
155+
result:
156+
"15e356c67d266d3ca85cff4f6d92d11720aae32cdd28d5d9885836dacb1d213b",
157+
},
158+
{
159+
msg: "efca4cdd31923b50f4214af5d2ae10e7ac45a5019e9431cc195482d707485378",
160+
key: "ccc0b35ea59c51a1e45af00502966237ccc0b35ea59c51a1e45af00502966237",
161+
iv,
162+
mode: "aes-256-ctr",
163+
result:
164+
"010bb6dc10ea201bf2d586de4741309373c07b6ddf30ad8502adf4dd0bda2d23",
165+
},
166+
{
167+
msg: "efca4cdd31923b50f4214af5d2ae10e7ac45a5019e9431cc195482d707485378efca4cdd31923b50f4214af5d2ae10e7ac45a5019e9431cc195482d707485378",
168+
key: "ccc0b35ea59c51a1e45af00502966237",
169+
iv,
170+
mode: "aes-128-ctr",
171+
result:
172+
"15e356c67d266d3ca85cff4f6d92d11720aae32cdd28d5d9885836dacb1d213b55f347e68f72acf46234d495f579fb45f9dcfc7dc688a9174f566d137ffc626c",
173+
},
174+
{
175+
msg: "efca4cdd31923b50f4214af5d2ae10e7ac45a5019e9431cc195482d707485378efca4cdd31923b50f4214af5d2ae10e7ac45a5019e9431cc195482d707485378",
176+
key: "ccc0b35ea59c51a1e45af00502966237ccc0b35ea59c51a1e45af00502966237",
177+
iv,
178+
mode: "aes-256-ctr",
179+
result:
180+
"010bb6dc10ea201bf2d586de4741309373c07b6ddf30ad8502adf4dd0bda2d23c436b35e5dfa0a0088dcb6ae7328f1ec66212099222ee1c18983b58513cf5f4c",
181+
},
182+
];
183+
for (const v of vectors) {
184+
const msg = hexToBytes(v.msg);
185+
const key = hexToBytes(v.key);
186+
const iv = hexToBytes(v.iv);
187+
const res = await encrypt(msg, key, iv, v.mode);
188+
deepStrictEqual(toHex(res), v.result);
189+
const clearText = await decrypt(res, key, iv, v.mode);
190+
deepStrictEqual(clearText, msg);
191+
}
192+
});
154193
});

Diff for: test/test-vectors/assert.ts

+3-7
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
11
// Minimal assert version to avoid dependecies on node internals
22
// Allows to verify that none of brwoserify version of node internals is included in resulting build
3-
async function deepStrictEqual(
4-
actual: unknown,
5-
expected: unknown,
6-
message?: string
7-
) {
3+
function deepStrictEqual(actual: unknown, expected: unknown, message?: string) {
84
const [actualType, expectedType] = [typeof actual, typeof expected];
95
const err = new Error(
106
`Non-equal values: actual=${actual} (type=${actualType}) expected=${expected} (type=${expectedType})${
@@ -49,7 +45,7 @@ async function deepStrictEqual(
4945
if (actualType === "object") {
5046
const [actualKeys, expectedKeys] = [
5147
Object.keys(actual as object),
52-
Object.keys(expected as object)
48+
Object.keys(expected as object),
5349
];
5450
deepStrictEqual(actualKeys, expectedKeys, message);
5551
for (const key of actualKeys) {
@@ -60,7 +56,7 @@ async function deepStrictEqual(
6056
throw err;
6157
}
6258

63-
async function throws(cb: () => any) {
59+
function throws(cb: () => any) {
6460
try {
6561
cb();
6662
} catch (e) {

0 commit comments

Comments
 (0)