JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 3358
  • Score
    100M100P100Q148607F
  • License Apache-2.0

Signatures, keys and Pedersen hash on STARK friendly elliptic curve

Package Exports

    This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@starkware-industries/starkware-crypto-utils) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

    Readme

    StarkWare Crypto Utils

    Signatures, keys and Pedersen hash on STARK friendly elliptic curve

    Installation

    // using npm
    npm i @starkware-industries/starkware-crypto-utils
    
    // using yarn
    yarn add @starkware-industries/starkware-crypto-utils

    How to use it

    const starkwareCrypto = require('@starkware-industries/starkware-crypto-utils');

    API

    {
        prime,
        ec: starkEc,
        constantPoints,
        shiftPoint,
        maxEcdsaVal, // Data.
        pedersen,
        getLimitOrderMsgHash,
        getTransferMsgHash,
        sign,
        verify,
        assertInRange,
        getTransferMsgHashWithFee,
        getLimitOrderMsgHashWithFee // Function.
    
        asset: {
          getAssetType,
          getAssetId // Function.
        },
    
        keyDerivation: {
          StarkExEc: ec.n, // Data.
          getPrivateKeyFromEthSignature,
          privateToStarkKey,
          getKeyPairFromPath,
          getAccountPath,
          grindKey // Function.
        },
    
        messageUtils: {
          assertInRange // Function.
        }
    }

    Usage

    Signing a StarkEx order

    const starkwareCrypto = require('@starkware-libs/starkware-crypto-utils');
    const testData = require('test/config/signature_test_data.json');
    
    const privateKey = testData.meta_data.party_a_order.private_key.substring(2);
    const keyPair = starkwareCrypto.ec.keyFromPrivate(privateKey, 'hex');
    const publicKey = starkwareCrypto.ec.keyFromPublic(
      keyPair.getPublic(true, 'hex'),
      'hex'
    );
    const publicKeyX = publicKey.pub.getX();
    
    assert(
      publicKeyX.toString(16) ===
        testData.settlement.party_a_order.public_key.substring(2),
      `Got: ${publicKeyX.toString(16)}.
            Expected: ${testData.settlement.party_a_order.public_key.substring(2)}`
    );
    
    const {party_a_order: partyAOrder} = testData.settlement;
    const msgHash = starkwareCrypto.getLimitOrderMsgHash(
      partyAOrder.vault_id_sell, // - vault_sell (uint31)
      partyAOrder.vault_id_buy, // - vault_buy (uint31)
      partyAOrder.amount_sell, // - amount_sell (uint63 decimal str)
      partyAOrder.amount_buy, // - amount_buy (uint63 decimal str)
      partyAOrder.token_sell, // - token_sell (hex str with 0x prefix < prime)
      partyAOrder.token_buy, // - token_buy (hex str with 0x prefix < prime)
      partyAOrder.nonce, // - nonce (uint31)
      partyAOrder.expiration_timestamp // - expiration_timestamp (uint22)
    );
    
    assert(
      msgHash === testData.meta_data.party_a_order.message_hash.substring(2),
      `Got: ${msgHash}. Expected: ` +
        testData.meta_data.party_a_order.message_hash.substring(2)
    );
    
    const msgSignature = starkwareCrypto.sign(keyPair, msgHash);
    const {r, s} = msgSignature;
    
    assert(starkwareCrypto.verify(publicKey, msgHash, msgSignature));
    assert(
      r.toString(16) === partyAOrder.signature.r.substring(2),
      `Got: ${r.toString(16)}. Expected: ${partyAOrder.signature.r.substring(2)}`
    );
    assert(
      s.toString(16) === partyAOrder.signature.s.substring(2),
      `Got: ${s.toString(16)}. Expected: ${partyAOrder.signature.s.substring(2)}`
    );
    
    // The following is the JSON representation of an order:
    console.log('Order JSON representation: ');
    console.log(partyAOrder);
    console.log('\n');

    StarkEx key serialization

    const starkwareCrypto = require('@starkware-libs/starkware-crypto-utils');
    
    const pubXStr = publicKey.pub.getX().toString('hex');
    const pubYStr = publicKey.pub.getY().toString('hex');
    
    // Verify Deserialization.
    const pubKeyDeserialized = starkwareCrypto.ec.keyFromPublic(
      {x: pubXStr, y: pubYStr},
      'hex'
    );
    assert(starkwareCrypto.verify(pubKeyDeserialized, msgHash, msgSignature));

    Signing a StarkEx order with fee

    const privateKey = testData.meta_data.party_a_order.private_key.substring(2);
    const keyPair = starkwareCrypto.ec.keyFromPrivate(privateKey, 'hex');
    const publicKey = starkwareCrypto.ec.keyFromPublic(
      keyPair.getPublic(true, 'hex'),
      'hex'
    );
    const publicKeyX = publicKey.pub.getX();
    
    assert(
      publicKeyX.toString(16) ===
        testData.settlement.party_a_order.public_key.substring(2),
      `Got: ${publicKeyX.toString(16)}.
            Expected: ${testData.settlement.party_a_order.public_key.substring(2)}`
    );
    
    const {party_a_order: partyAOrder} = testData.settlement;
    const feeInfo = testData.fee_info_user;
    const msgHash = starkwareCrypto.getLimitOrderMsgHashWithFee(
      partyAOrder.vault_id_sell, // - vault_sell (uint64)
      partyAOrder.vault_id_buy, // - vault_buy (uint64)
      partyAOrder.amount_sell, // - amount_sell (uint63 decimal str)
      partyAOrder.amount_buy, // - amount_buy (uint63 decimal str)
      partyAOrder.token_sell, // - token_sell (hex str with 0x prefix < prime)
      partyAOrder.token_buy, // - token_buy (hex str with 0x prefix < prime)
      partyAOrder.nonce, // - nonce (uint31)
      partyAOrder.expiration_timestamp, // - expiration_timestamp (uint22)
      feeInfo.token_id, // - token (hex str with 0x prefix < prime)
      feeInfo.source_vault_id, // - fee_source_vault_id (uint31)
      feeInfo.fee_limit // - amount (uint63 decimal str)
    );
    
    assert(
      msgHash ===
        testData.meta_data.party_a_order_with_fee.message_hash.substring(2),
      `Got: ${msgHash}. Expected: ` +
        testData.meta_data.party_a_order_with_fee.message_hash.substring(2)
    );
    
    // The following is the JSON representation of an order:
    console.log('Order With Fee JSON representation: ');
    // Fee info is added to the order, and will be also be seen in the JSON of Settlement.
    partyAOrder.fee_info = feeInfo; // eslint-disable-line
    console.log(partyAOrder);
    console.log('\n');

    StarkEx transfer

    const starkwareCrypto = require('@starkware-libs/starkware-crypto-utils');
    const testData = require('test/config/signature_test_data.json');
    
    const privateKey = testData.meta_data.transfer_order.private_key.substring(2);
    const keyPair = starkwareCrypto.ec.keyFromPrivate(privateKey, 'hex');
    const publicKey = starkwareCrypto.ec.keyFromPublic(
      keyPair.getPublic(true, 'hex'),
      'hex'
    );
    const publicKeyX = publicKey.pub.getX();
    
    assert(
      publicKeyX.toString(16) === testData.transfer_order.public_key.substring(2),
      `Got: ${publicKeyX.toString(16)}.
                Expected: ${testData.transfer_order.public_key.substring(2)}`
    );
    
    const transfer = testData.transfer_order;
    const msgHash = starkwareCrypto.getTransferMsgHash(
      transfer.amount, // - amount (uint63 decimal str)
      transfer.nonce, // - nonce (uint31)
      transfer.sender_vault_id, // - sender_vault_id (uint31)
      transfer.token, // - token (hex str with 0x prefix < prime)
      transfer.target_vault_id, // - target_vault_id (uint31)
      transfer.target_public_key, // - target_public_key (hex str with 0x prefix < prime)
      transfer.expiration_timestamp // - expiration_timestamp (uint22)
    );
    
    assert(
      msgHash === testData.meta_data.transfer_order.message_hash.substring(2),
      `Got: ${msgHash}. Expected: ` +
        testData.meta_data.transfer_order.message_hash.substring(2)
    );
    
    // The following is the JSON representation of a transfer:
    console.log('Transfer JSON representation: ');
    console.log(transfer);
    console.log('\n');

    StarkEx conditional transfer

    const starkwareCrypto = require('@starkware-libs/starkware-crypto-utils');
    const testData = require('test/config/signature_test_data.json');
    
    const privateKey =
      testData.meta_data.conditional_transfer_order.private_key.substring(2);
    const keyPair = starkwareCrypto.ec.keyFromPrivate(privateKey, 'hex');
    const publicKey = starkwareCrypto.ec.keyFromPublic(
      keyPair.getPublic(true, 'hex'),
      'hex'
    );
    const publicKeyX = publicKey.pub.getX();
    
    assert(
      publicKeyX.toString(16) ===
        testData.conditional_transfer_order.public_key.substring(2),
      `Got: ${publicKeyX.toString(16)}.
            Expected: ${testData.conditional_transfer_order.public_key.substring(
              2
            )}`
    );
    
    const transfer = testData.conditional_transfer_order;
    const msgHash = starkwareCrypto.getTransferMsgHash(
      transfer.amount, // - amount (uint63 decimal str)
      transfer.nonce, // - nonce (uint31)
      transfer.sender_vault_id, // - sender_vault_id (uint31)
      transfer.token, // - token (hex str with 0x prefix < prime)
      transfer.target_vault_id, // - target_vault_id (uint31)
      transfer.target_public_key, // - target_public_key (hex str with 0x prefix < prime)
      transfer.expiration_timestamp, // - expiration_timestamp (uint22)
      transfer.condition // - condition (hex str with 0x prefix < prime)
    );
    
    assert(
      msgHash ===
        testData.meta_data.conditional_transfer_order.message_hash.substring(2),
      `Got: ${msgHash}. Expected: ` +
        testData.meta_data.conditional_transfer_order.message_hash.substring(2)
    );
    
    // The following is the JSON representation of a transfer:
    console.log('Conditional Transfer JSON representation: ');
    console.log(transfer);
    console.log('\n');

    StarkEx transfer with fee

    const privateKey = testData.meta_data.transfer_order.private_key.substring(2);
    const keyPair = starkwareCrypto.ec.keyFromPrivate(privateKey, 'hex');
    const publicKey = starkwareCrypto.ec.keyFromPublic(
      keyPair.getPublic(true, 'hex'),
      'hex'
    );
    const publicKeyX = publicKey.pub.getX();
    
    assert(
      publicKeyX.toString(16) === testData.transfer_order.public_key.substring(2),
      `Got: ${publicKeyX.toString(16)}.
            Expected: ${testData.transfer_order.public_key.substring(2)}`
    );
    
    const transfer = testData.transfer_order;
    const feeInfo = testData.fee_info_user;
    const msgHash = starkwareCrypto.getTransferMsgHashWithFee(
      transfer.amount, // - amount (uint63 decimal str)
      transfer.nonce, // - nonce (uint31)
      transfer.sender_vault_id, // - sender_vault_id (uint64)
      transfer.token, // - token (hex str with 0x prefix < prime)
      transfer.target_vault_id, // - target_vault_id (uint64)
      transfer.target_public_key, // - target_public_key (hex str with 0x prefix < prime)
      transfer.expiration_timestamp, // - expiration_timestamp (uint22)
      feeInfo.token_id, // - token (hex str with 0x prefix < prime)
      feeInfo.source_vault_id, // - fee_source_vault_id (uint64)
      feeInfo.fee_limit // - amount (uint63 decimal str)
    );
    
    assert(
      msgHash ===
        testData.meta_data.transfer_order_with_fee.message_hash.substring(2),
      `Got: ${msgHash}. Expected: ` +
        testData.meta_data.transfer_order.message_hash.substring(2)
    );
    
    // The following is the JSON representation of a transfer:
    console.log('Transfer With Fee JSON representation: ');
    console.log(transfer);
    console.log('\n');

    StarkEx conditional Transfer with fee

    const privateKey =
      testData.meta_data.conditional_transfer_order.private_key.substring(2);
    const keyPair = starkwareCrypto.ec.keyFromPrivate(privateKey, 'hex');
    const publicKey = starkwareCrypto.ec.keyFromPublic(
      keyPair.getPublic(true, 'hex'),
      'hex'
    );
    const publicKeyX = publicKey.pub.getX();
    
    assert(
      publicKeyX.toString(16) ===
        testData.conditional_transfer_order.public_key.substring(2),
      `Got: ${publicKeyX.toString(16)}.
            Expected: ${testData.conditional_transfer_order.public_key.substring(
              2
            )}`
    );
    
    const transfer = testData.conditional_transfer_order;
    const feeInfo = testData.fee_info_user;
    const msgHash = starkwareCrypto.getTransferMsgHashWithFee(
      transfer.amount, // - amount (uint63 decimal str)
      transfer.nonce, // - nonce (uint31)
      transfer.sender_vault_id, // - sender_vault_id (uint64)
      transfer.token, // - token (hex str with 0x prefix < prime)
      transfer.target_vault_id, // - target_vault_id (uint64)
      transfer.target_public_key, // - target_public_key (hex str with 0x prefix < prime)
      transfer.expiration_timestamp, // - expiration_timestamp (uint22)
      feeInfo.token_id, // - token (hex str with 0x prefix < prime)
      feeInfo.source_vault_id, // - fee_source_vault_id (uint64)
      feeInfo.fee_limit, // - amount (uint63 decimal str)
      transfer.condition // - condition (hex str with 0x prefix < prime)
    );
    
    assert(
      msgHash ===
        testData.meta_data.conditional_transfer_order_with_fee.message_hash.substring(
          2
        ),
      `Got: ${msgHash}. Expected: ` +
        testData.meta_data.conditional_transfer_order.message_hash.substring(2)
    );
    
    // The following is the JSON representation of a transfer:
    console.log('Conditional Transfer With Fee JSON representation: ');
    console.log(transfer);
    console.log('\n');

    Adding a matching order to create a settlement

    const starkwareCrypto = require('@starkware-libs/starkware-crypto-utils');
    const testData = require('test/config/signature_test_data.json');
    
    const privateKey = testData.meta_data.party_b_order.private_key.substring(2);
    const keyPair = starkwareCrypto.ec.keyFromPrivate(privateKey, 'hex');
    const publicKey = starkwareCrypto.ec.keyFromPublic(
      keyPair.getPublic(true, 'hex'),
      'hex'
    );
    const publicKeyX = publicKey.pub.getX();
    
    assert(
      publicKeyX.toString(16) ===
        testData.settlement.party_b_order.public_key.substring(2),
      `Got: ${publicKeyX.toString(16)}.
            Expected: ${testData.settlement.party_b_order.public_key.substring(2)}`
    );
    
    const {party_b_order: partyBOrder} = testData.settlement;
    const msgHash = starkwareCrypto.getLimitOrderMsgHash(
      partyBOrder.vault_id_sell, // - vault_sell (uint31)
      partyBOrder.vault_id_buy, // - vault_buy (uint31)
      partyBOrder.amount_sell, // - amount_sell (uint63 decimal str)
      partyBOrder.amount_buy, // - amount_buy (uint63 decimal str)
      partyBOrder.token_sell, // - token_sell (hex str with 0x prefix < prime)
      partyBOrder.token_buy, // - token_buy (hex str with 0x prefix < prime)
      partyBOrder.nonce, // - nonce (uint31)
      partyBOrder.expiration_timestamp // - expiration_timestamp (uint22)
    );
    
    assert(
      msgHash === testData.meta_data.party_b_order.message_hash.substring(2),
      `Got: ${msgHash}. Expected: ` +
        testData.meta_data.party_b_order.message_hash.substring(2)
    );
    
    const msgSignature = starkwareCrypto.sign(keyPair, msgHash);
    const {r, s} = msgSignature;
    
    assert(starkwareCrypto.verify(publicKey, msgHash, msgSignature));
    assert(
      r.toString(16) === partyBOrder.signature.r.substring(2),
      `Got: ${r.toString(16)}. Expected: ${partyBOrder.signature.r.substring(2)}`
    );
    assert(
      s.toString(16) === partyBOrder.signature.s.substring(2),
      `Got: ${s.toString(16)}. Expected: ${partyBOrder.signature.s.substring(2)}`
    );
    
    // The following is the JSON representation of a settlement:
    console.log('Settlement JSON representation: ');
    console.log(testData.settlement);

    Valid transfer with sender_vault_id=2**63+10

    const transfer = testData.transfer_order_2nd_valid_range;
    const feeInfo = testData.fee_info_user;
    
    const msgHash = starkwareCrypto.getTransferMsgHashWithFee(
      transfer.amount, // - amount (uint63 decimal str)
      transfer.nonce, // - nonce (uint31)
      transfer.sender_vault_id, // - sender_vault_id (uint64)
      transfer.token, // - token (hex str with 0x prefix < prime)
      transfer.target_vault_id, // - target_vault_id (uint64)
      transfer.target_public_key, // - target_public_key (hex str with 0x prefix < prime)
      transfer.expiration_timestamp, // - expiration_timestamp (uint22)
      feeInfo.token_id, // - token (hex str with 0x prefix < prime)
      feeInfo.source_vault_id, // - fee_source_vault_id (uint64)
      feeInfo.fee_limit, // - amount (uint63 decimal str)
      transfer.condition // - condition (hex str with 0x prefix < prime)
    );
    
    assert(
      msgHash ===
        testData.meta_data.transfer_order_2nd_valid_range.message_hash.substring(2),
      `Got: ${msgHash}. Expected: ` +
        testData.meta_data.transfer_order_2nd_valid_range.message_hash.substring(2)
    );
    
    // The following is the JSON representation of a transfer with sender_vault_id in the second
    // valid range:
    console.log('Transfer JSON representation: ');
    console.log(transfer);
    console.log('\n');

    License

    Apache License 2.0