Skip to content

Commit

Permalink
sign: allow any length of extraEntropy option
Browse files Browse the repository at this point in the history
  • Loading branch information
paulmillr committed Nov 20, 2024
1 parent 76684c9 commit 3be0efc
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 24 deletions.
10 changes: 2 additions & 8 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -290,14 +290,8 @@ const prepSig = (msgh, priv, opts = optS) => {
const d = toPriv(priv); // validate private key, convert to bigint
const seed = [i2o(d), h1o]; // Step D of RFC6979 3.2
let ent = opts.extraEntropy; // RFC6979 3.6: additional k' (optional)
if (ent) { // K = HMAC_K(V || 0x00 || int2octets(x) || bits2octets(h1) || k')
if (ent === true)
ent = etc.randomBytes(fLen); // if true, use CSPRNG to generate data
const e = toU8(ent); // convert Hex|Bytes to Bytes
if (e.length !== fLen)
err(); // Expected 32 bytes of extra data
seed.push(e);
}
if (ent) // K = HMAC_K(V || 0x00 || int2octets(x) || bits2octets(h1) || k')
seed.push(ent === true ? etc.randomBytes(fLen) : toU8(ent)); // true == fetch from CSPRNG
const m = h1i; // convert msg to bigint
const k2sig = (kBytes) => {
const k = bits2int(kBytes); // RFC6979 method.
Expand Down
8 changes: 2 additions & 6 deletions index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -246,12 +246,8 @@ const prepSig = (msgh: Hex, priv: PrivKey, opts=optS): BC => {// prepare for RFC
const d = toPriv(priv); // validate private key, convert to bigint
const seed = [i2o(d), h1o]; // Step D of RFC6979 3.2
let ent = opts.extraEntropy; // RFC6979 3.6: additional k' (optional)
if (ent) { // K = HMAC_K(V || 0x00 || int2octets(x) || bits2octets(h1) || k')
if (ent === true) ent = etc.randomBytes(fLen); // if true, use CSPRNG to generate data
const e = toU8(ent); // convert Hex|Bytes to Bytes
if (e.length !== fLen) err(); // Expected 32 bytes of extra data
seed.push(e);
}
if (ent) // K = HMAC_K(V || 0x00 || int2octets(x) || bits2octets(h1) || k')
seed.push(ent === true ? etc.randomBytes(fLen) : toU8(ent)); // true == fetch from CSPRNG
const m = h1i; // convert msg to bigint
const k2sig = (kBytes: Bytes): SignatureWithRecovery | undefined => { // Transform k => Signature.
const k = bits2int(kBytes); // RFC6979 method.
Expand Down
52 changes: 42 additions & 10 deletions test/secp256k1.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -204,8 +204,10 @@ describe('secp256k1', () => {
const priv = 'c509ae2138ddca15f6b33062cd3bf76351c79f58c82ee2c2236d835bdea19d13';
const msg = 'b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9';

const hi = 'a6bf36d52da4eef85a513a88d81996a47804a2390c9910c0bd35488effca36bf8bf1f9232ab0efe4a93704ae871aa953b34d1000cef59c9d33fcc696f935108d';
const lo = 'a6bf36d52da4eef85a513a88d81996a47804a2390c9910c0bd35488effca36bf740e06dcd54f101b56c8fb5178e556ab0761cce5e053039e8bd597f5d70130b4';
const hi =
'a6bf36d52da4eef85a513a88d81996a47804a2390c9910c0bd35488effca36bf8bf1f9232ab0efe4a93704ae871aa953b34d1000cef59c9d33fcc696f935108d';
const lo =
'a6bf36d52da4eef85a513a88d81996a47804a2390c9910c0bd35488effca36bf740e06dcd54f101b56c8fb5178e556ab0761cce5e053039e8bd597f5d70130b4';
const hi_ = new secp.Signature(
75421779095773161492578598757717572512754773103551662129966816753283695785663n,
63299015578620006752099543153250095157058828301739590985992016204296254460045n,
Expand Down Expand Up @@ -310,6 +312,33 @@ describe('secp256k1', () => {
deepStrictEqual(sign(ent5), e.extraEntropyMax);
}
});

should('handle one byte {extraEntropy}', () => {
const extraEntropy = '01';
const privKey = hexToBytes(
'0101010101010101010101010101010101010101010101010101010101010101'
);
const msg = 'd1a9dc8ed4e46a6a3e5e594615ca351d7d7ef44df1e4c94c1802f3592183794b';
const res = secp.sign(msg, privKey, { extraEntropy }).toCompactHex();
deepStrictEqual(
res,
'a250ec23a54bfdecf0e924cbf484077c5044410f915cdba86731cb2e4e925aaa5b1e4e3553d88be2c48a9a0d8d849ce2cc5720d25b2f97473e02f2550abe9545'
);
});

should('handle 48 bytes {extraEntropy}', () => {
const extraEntropy =
'000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000001';
const privKey = hexToBytes(
'0101010101010101010101010101010101010101010101010101010101010101'
);
const msg = 'd1a9dc8ed4e46a6a3e5e594615ca351d7d7ef44df1e4c94c1802f3592183794b';
const res = secp.sign(msg, privKey, { extraEntropy }).toCompactHex();
deepStrictEqual(
res,
'2bdf40f42ac0e42ee12750d03bb12b75306dae58eb3c961c5a80d78efae93e595295b66e8eb28f1eb046bb129a976340312159ec0c20b97342667572e4a8379a'
);
});
});

describe('verify()', () => {
Expand All @@ -323,7 +352,6 @@ describe('secp256k1', () => {
if (secp.signAsync) {
const signature = await secp.signAsync(MSG, PRIV_KEY);
deepStrictEqual(secp.verify(signature, MSG, publicKey), true);

}
});
should(' not verify signature with wrong public key', async () => {
Expand All @@ -350,15 +378,19 @@ describe('secp256k1', () => {
});
should('verify random signatures', () =>
fc.assert(
fc.asyncProperty(FC_BIGINT, fc.hexaString({ minLength: 64, maxLength: 64 }), async (privKey, msg) => {
const pub = secp.getPublicKey(privKey);
const sig = secp.sign(msg, privKey);
deepStrictEqual(secp.verify(sig, msg, pub), true);
if (secp.signAsync) {
const sig = await secp.signAsync(msg, privKey);
fc.asyncProperty(
FC_BIGINT,
fc.hexaString({ minLength: 64, maxLength: 64 }),
async (privKey, msg) => {
const pub = secp.getPublicKey(privKey);
const sig = secp.sign(msg, privKey);
deepStrictEqual(secp.verify(sig, msg, pub), true);
if (secp.signAsync) {
const sig = await secp.signAsync(msg, privKey);
deepStrictEqual(secp.verify(sig, msg, pub), true);
}
}
})
)
)
);
should('not verify signature with invalid r/s', () => {
Expand Down

0 comments on commit 3be0efc

Please sign in to comment.