var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
import { ArrayUtility } from '../../src/utils/array.js';
import { base64url } from 'multiformats/bases/base64';
import { DwnErrorCode } from '../../src/core/dwn-error.js';
import { expect } from 'chai';
import { Secp256k1 } from '../../src/utils/secp256k1.js';
import { TestDataGenerator } from './test-data-generator.js';
describe('Secp256k1', () => {
    if (process.env.TESTSOFF === 'true') {
        return;
    }
    describe('validateKey()', () => {
        it('should throw if key is not a valid SECP256K1 key', () => __awaiter(void 0, void 0, void 0, function* () {
            const validKey = (yield Secp256k1.generateKeyPair()).publicJwk;
            expect(() => Secp256k1.validateKey(Object.assign(Object.assign({}, validKey), { kty: 'invalidKty' }))).to.throw(DwnErrorCode.Secp256k1KeyNotValid);
            expect(() => Secp256k1.validateKey(Object.assign(Object.assign({}, validKey), { crv: 'invalidCrv' }))).to.throw(DwnErrorCode.Secp256k1KeyNotValid);
        }));
    });
    describe('publicKeyToJwk()', () => {
        it('should generate the same JWK regardless of compressed or compressed public key bytes given', () => __awaiter(void 0, void 0, void 0, function* () {
            const compressedPublicKeyBase64UrlString = 'A5roVr1J6MufaaBwweb5Q75PrZCbZpzC55kTCO68ylMs';
            const uncompressedPublicKeyBase64UrlString = 'BJroVr1J6MufaaBwweb5Q75PrZCbZpzC55kTCO68ylMsyC3G4QfbKeDzIr2BwyMUQ3Na1mxPvwxJ8GBMO3jkGL0';
            const compressedPublicKey = base64url.baseDecode(compressedPublicKeyBase64UrlString);
            const uncompressedPublicKey = base64url.baseDecode(uncompressedPublicKeyBase64UrlString);
            const publicJwk1 = yield Secp256k1.publicKeyToJwk(compressedPublicKey);
            const publicJwk2 = yield Secp256k1.publicKeyToJwk(uncompressedPublicKey);
            expect(publicJwk1.x).to.equal(publicJwk2.x);
            expect(publicJwk1.y).to.equal(publicJwk2.y);
        }));
    });
    describe('sign()', () => {
        it('should generate the signature in compact format', () => __awaiter(void 0, void 0, void 0, function* () {
            const { privateJwk } = yield Secp256k1.generateKeyPair();
            const contentBytes = TestDataGenerator.randomBytes(16);
            const signatureBytes = yield Secp256k1.sign(contentBytes, privateJwk);
            expect(signatureBytes.length).to.equal(64); // DER format would be 70 bytes
        }));
    });
    describe('deriveChildPublic/PrivateKey()', () => {
        it('should derive the same key pair counterparts when given the same tweak input', () => __awaiter(void 0, void 0, void 0, function* () {
            const { publicKey, privateKey } = yield Secp256k1.generateKeyPairRaw();
            const tweakInput = TestDataGenerator.randomBytes(32);
            const derivedPrivateKey = Secp256k1.deriveChildPrivateKey(privateKey, tweakInput);
            const derivedPublicKey = Secp256k1.deriveChildPublicKey(publicKey, tweakInput);
            const publicKeyFromDerivedPrivateKey = yield Secp256k1.getPublicKey(derivedPrivateKey);
            expect(ArrayUtility.byteArraysEqual(derivedPublicKey, publicKeyFromDerivedPrivateKey)).to.be.true;
        }));
    });
    describe('derivePublic/PrivateKey()', () => {
        it('should be able to derive same key using different ancestor along the chain path', () => __awaiter(void 0, void 0, void 0, function* () {
            const { publicKey, privateKey } = yield Secp256k1.generateKeyPairRaw();
            const fullPathToG = ['a', 'b', 'c', 'd', 'e', 'f', 'g'];
            const fullPathToD = ['a', 'b', 'c', 'd'];
            const relativePathFromDToG = ['e', 'f', 'g'];
            // testing public key derivation from different ancestor in the same chain
            const publicKeyG = yield Secp256k1.derivePublicKey(publicKey, fullPathToG);
            const publicKeyD = yield Secp256k1.derivePublicKey(publicKey, fullPathToD);
            const publicKeyGFromD = yield Secp256k1.derivePublicKey(publicKeyD, relativePathFromDToG);
            expect(ArrayUtility.byteArraysEqual(publicKeyG, publicKeyGFromD)).to.be.true;
            // testing private key derivation from different ancestor in the same chain
            const privateKeyG = yield Secp256k1.derivePrivateKey(privateKey, fullPathToG);
            const privateKeyD = yield Secp256k1.derivePrivateKey(privateKey, fullPathToD);
            const privateKeyGFromD = yield Secp256k1.derivePrivateKey(privateKeyD, relativePathFromDToG);
            expect(ArrayUtility.byteArraysEqual(privateKeyG, privateKeyGFromD)).to.be.true;
            // testing that the derived private key matches up with the derived public key
            const publicKeyGFromPrivateKeyG = yield Secp256k1.getPublicKey(privateKeyG);
            expect(ArrayUtility.byteArraysEqual(publicKeyGFromPrivateKeyG, publicKeyG)).to.be.true;
        }));
        it('should derive the same public key using either the private or public counterpart of the same key pair', () => __awaiter(void 0, void 0, void 0, function* () {
            const { publicKey, privateKey } = yield Secp256k1.generateKeyPairRaw();
            const path = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10'];
            const derivedKeyFromPublicKey = yield Secp256k1.derivePublicKey(publicKey, path);
            const derivedKeyFromPrivateKey = yield Secp256k1.derivePublicKey(privateKey, path);
            expect(ArrayUtility.byteArraysEqual(derivedKeyFromPublicKey, derivedKeyFromPrivateKey)).to.be.true;
        }));
        it('should derive the same public key using either the private or public counterpart of the same key pair', () => __awaiter(void 0, void 0, void 0, function* () {
            const { publicKey, privateKey } = yield Secp256k1.generateKeyPairRaw();
            const invalidPath = ['should not have segment with empty string', ''];
            yield expect(Secp256k1.derivePublicKey(publicKey, invalidPath)).to.be.rejectedWith(DwnErrorCode.HdKeyDerivationPathInvalid);
            yield expect(Secp256k1.derivePrivateKey(privateKey, invalidPath)).to.be.rejectedWith(DwnErrorCode.HdKeyDerivationPathInvalid);
        }));
    });
});
//# sourceMappingURL=secp256k1.spec.js.map