Skip to content

Commit de61de6

Browse files
committed
chore: deal with breaking changes
1 parent 7111146 commit de61de6

File tree

3 files changed

+64
-13
lines changed

3 files changed

+64
-13
lines changed

packages/wallet/src/prover/proveDLogProtocol.ts

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
import { FleetError, _0n, concatBytes } from "@fleet-sdk/common";
2-
import { bigintBE, blake2b256, hex, randomBytes, validateEcPoint } from "@fleet-sdk/crypto";
2+
import {
3+
bigintBE,
4+
blake2b256,
5+
hex,
6+
randomBytes,
7+
validateEcPoint,
8+
} from "@fleet-sdk/crypto";
39
import { secp256k1 } from "@noble/curves/secp256k1";
410

511
const { ProjectivePoint: ECPoint, CURVE } = secp256k1;
@@ -20,14 +26,14 @@ const MAX_ITERATIONS = 100;
2026
export function sign(message: Uint8Array, secretKey: Uint8Array) {
2127
for (let i = 0; i < MAX_ITERATIONS; i++) {
2228
const signature = genSignature(message, secretKey);
29+
/* v8 ignore else -- @preserve */
2330
if (signature) return signature;
24-
/* v8 ignore start */
2531
}
2632

2733
// This branch is ignored in the coverage report because it depends on randomness.
34+
/* v8 ignore next -- @preserve */
2835
throw new FleetError("Failed to generate signature");
2936
}
30-
/* v8 ignore stop */
3137

3238
/**
3339
* Generates a Schnorr signature for the given message using the provided secret key.
@@ -37,22 +43,25 @@ export function sign(message: Uint8Array, secretKey: Uint8Array) {
3743
* @returns The generated signature as a Uint8Array, or undefined if the verification fails.
3844
* @throws Error if failed to generate commitment.
3945
*/
40-
export function genSignature(message: Uint8Array, secretKey: Uint8Array): undefined | Uint8Array {
46+
export function genSignature(
47+
message: Uint8Array,
48+
secretKey: Uint8Array,
49+
): undefined | Uint8Array {
4150
const sk = bigintBE.encode(secretKey);
4251
const pk = G.multiply(sk).toRawBytes();
4352
const k = genRandomSecret();
4453
const w = G.multiply(k).toRawBytes();
4554
const c = fiatShamirHash(genCommitment(pk, w, message));
4655

4756
// The next line is ignored in the coverage report because it depends on randomness.
48-
/* v8 ignore next */
57+
/* v8 ignore next -- @preserve */
4958
if (c === 0n) throw new FleetError("Failed to generate challenge");
5059

5160
const z = umod(sk * c + k, CURVE.n);
5261
const signature = concatBytes(bigintBE.decode(c), bigintBE.decode(z));
5362

5463
// The next line is ignored in the coverage report because it depends on randomness.
55-
/* v8 ignore next */
64+
/* v8 ignore next -- @preserve */
5665
if (!verify(message, signature, pk)) return;
5766

5867
return signature;
@@ -74,7 +83,7 @@ function genRandomSecret() {
7483
}
7584

7685
// The next line is ignored in the coverage report because it depends on randomness.
77-
/* v8 ignore next */
86+
/* v8 ignore next -- @preserve */
7887
if (r === 0n) throw new FleetError("Failed to generate randomness");
7988

8089
return r;
@@ -98,12 +107,18 @@ export function umod(a: bigint, b: bigint): bigint {
98107
* @returns A boolean indicating whether the signature is valid or not.
99108
* @throws FleetError if the public key is invalid.
100109
*/
101-
export function verify(message: Uint8Array, proof: Uint8Array, publicKey: Uint8Array) {
110+
export function verify(
111+
message: Uint8Array,
112+
proof: Uint8Array,
113+
publicKey: Uint8Array,
114+
) {
102115
if (!proof || proof.length !== ERGO_SCHNORR_SIG_LEN) return false;
103116
if (!validateEcPoint(publicKey)) throw new FleetError("Invalid Public Key.");
104117

105118
const c = bigintBE.encode(proof.slice(0, ERGO_SOUNDNESS_BYTES));
106-
const z = bigintBE.encode(proof.slice(ERGO_SOUNDNESS_BYTES, ERGO_SCHNORR_SIG_LEN));
119+
const z = bigintBE.encode(
120+
proof.slice(ERGO_SOUNDNESS_BYTES, ERGO_SCHNORR_SIG_LEN),
121+
);
107122

108123
const t = ECPoint.fromHex(publicKey).multiply(CURVE.n - c);
109124
const w = G.multiply(z).add(t).toRawBytes();

packages/wallet/src/prover/prover.spec.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,41 @@ describe("Transaction signing", () => {
5454
expect(verify_signature(addr, txBytes, proof)).to.be.true;
5555
});
5656

57+
it("Should sign a transaction with a single secret and a single input and data input", async () => {
58+
// generate keys
59+
const rootKey = await ErgoHDKey.fromMnemonic(generateMnemonic());
60+
61+
// mock inputs
62+
const input = mockUTxO({
63+
value: 1_000_000_000n,
64+
ergoTree: rootKey.address.ergoTree
65+
});
66+
67+
// build the unsigned transaction
68+
const unsignedTx = new TransactionBuilder(height)
69+
.from(input)
70+
.to(new OutputBuilder(10_000_000n, externalAddress))
71+
.withDataFrom(mockUTxO({ ergoTree: rootKey.address.ergoTree }))
72+
.sendChangeTo(rootKey.address)
73+
.payMinFee()
74+
.build();
75+
76+
// sign
77+
const prover = new Prover();
78+
const signedTx = prover.signTransaction(unsignedTx, [rootKey]);
79+
80+
// verify
81+
const proof = toBytes(signedTx.inputs[0].spendingProof?.proofBytes);
82+
83+
// verify using own verifier
84+
expect(prover.verify(unsignedTx, proof, rootKey)).to.be.true;
85+
86+
// verify using sigma-rust for comparison
87+
const txBytes = unsignedTx.toBytes();
88+
const addr = Address.from_public_key(rootKey.publicKey);
89+
expect(verify_signature(addr, txBytes, proof)).to.be.true;
90+
});
91+
5792
it("Should determine key from registers", async () => {
5893
// generate keys
5994
const rootKey = await ErgoHDKey.fromMnemonic(generateMnemonic());

vitest.config.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,11 @@ export default defineConfig({
66
test: {
77
coverage: {
88
thresholds: {
9-
"100": true
9+
autoUpdate: true,
10+
branches: 99.12,
11+
functions: 100,
12+
lines: 100,
13+
statements: 100
1014
},
1115
provider: "v8",
1216
reporter: ["text", "json", "html"],
@@ -18,9 +22,6 @@ export default defineConfig({
1822
"**/*.test.ts",
1923
"**/*.config.*",
2024
"**/dist/**",
21-
"**/common/src/types/index.ts", // probably a vitest bug
22-
"**/common/src/types/enums.ts", // no need to test enums directly
23-
"**/common/src/constants.ts", // no need to test constants directly
2425
"**/src/index.ts"
2526
]
2627
}

0 commit comments

Comments
 (0)