JSPM

  • Created
  • Published
  • Downloads 98
  • Score
    100M100P100Q108505F
  • License MIT

BITBOX SDK for Bitcoin Cash

Package Exports

  • bitbox-sdk
  • bitbox-sdk/lib/Address
  • bitbox-sdk/lib/BITBOX
  • bitbox-sdk/lib/ECPair
  • bitbox-sdk/lib/HDNode

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 (bitbox-sdk) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

BITBOX SDK

bitbox-sdk is a utility for creating great Bitcoin Cash applications. It can be used from the command line or from within client/server apps.

Extensive documentation available at:

Open Source / Creative Commons Listings

Font awesome

Cube icon available under CC v4.0

More info

//Schnorr
const Buffer = require("safe-buffer").Buffer
const BigInteger = require("bigi")

// signing
const privateKey = BigInteger.fromHex(
  "B7E151628AED2A6ABF7158809CF4F3C762E7160F38B4DA56A784D9045190CFEF"
)
const message = Buffer.from(
  "243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89",
  "hex"
)
const createdSignature = BITBOX.Schnorr.sign(privateKey, message)
console.log("The signature is: " + createdSignature.toString("hex"))

// verifying
const publicKey = Buffer.from(
  "02DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659",
  "hex"
)
const signatureToVerify = Buffer.from(
  "2A298DACAE57395A15D0795DDBFD1DCB564DA82B0F269BC70A74F8220429BA1D1E51A22CCEC35599B8F266912281F8365FFC2D035A230434A1A64DC59F7013FD",
  "hex"
)
try {
  BITBOX.Schnorr.verify(publicKey, message, signatureToVerify)
  console.log("The signature is valid.")
} catch (e) {
  console.error("The signature verification failed: " + e)
}

// batch verifying
const publicKeys = [
  Buffer.from(
    "02DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659",
    "hex"
  ),
  Buffer.from(
    "03FAC2114C2FBB091527EB7C64ECB11F8021CB45E8E7809D3C0938E4B8C0E5F84B",
    "hex"
  ),
  Buffer.from(
    "026D7F1D87AB3BBC8BC01F95D9AECE1E659D6E33C880F8EFA65FACF83E698BBBF7",
    "hex"
  )
]
const messages = [
  Buffer.from(
    "243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89",
    "hex"
  ),
  Buffer.from(
    "5E2D58D8B3BCDF1ABADEC7829054F90DDA9805AAB56C77333024B9D0A508B75C",
    "hex"
  ),
  Buffer.from(
    "B2F0CD8ECB23C1710903F872C31B0FD37E15224AF457722A87C5E0C7F50FFFB3",
    "hex"
  )
]
const signatures = [
  Buffer.from(
    "2A298DACAE57395A15D0795DDBFD1DCB564DA82B0F269BC70A74F8220429BA1D1E51A22CCEC35599B8F266912281F8365FFC2D035A230434A1A64DC59F7013FD",
    "hex"
  ),
  Buffer.from(
    "00DA9B08172A9B6F0466A2DEFD817F2D7AB437E0D253CB5395A963866B3574BE00880371D01766935B92D2AB4CD5C8A2A5837EC57FED7660773A05F0DE142380",
    "hex"
  ),
  Buffer.from(
    "68CA1CC46F291A385E7C255562068357F964532300BEADFFB72DD93668C0C1CAC8D26132EB3200B86D66DE9C661A464C6B2293BB9A9F5B966E53CA736C7E504F",
    "hex"
  )
]
try {
  BITBOX.Schnorr.batchVerify(publicKeys, messages, signatures)
  console.log("The signatures are valid.")
} catch (e) {
  console.error("The signature verification failed: " + e)
}
const Buffer = require("safe-buffer").Buffer
const BigInteger = require("bigi")

const privateKey1 = BigInteger.fromHex(
  "B7E151628AED2A6ABF7158809CF4F3C762E7160F38B4DA56A784D9045190CFEF"
)
const privateKey2 = BigInteger.fromHex(
  "C90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B14E5C7"
)
const message = Buffer.from(
  "243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89",
  "hex"
)
const aggregatedSignature = BITBOX.Schnorr.nonInteractive(
  [privateKey1, privateKey2],
  message
)

// verifying an aggregated signature
const publicKey1 = Buffer.from(
  "02DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659",
  "hex"
)
const publicKey2 = Buffer.from(
  "03FAC2114C2FBB091527EB7C64ECB11F8021CB45E8E7809D3C0938E4B8C0E5F84B",
  "hex"
)
const X = BITBOX.Schnorr.pubKeyCombine([publicKey1, publicKey2])
try {
  BITBOX.Schnorr.verify(X, message, aggregatedSignature)
  console.log("The signature is valid.")
} catch (e) {
  console.error("The signature verification failed: " + e)
}
const Buffer = require("safe-buffer").Buffer
const BigInteger = require("bigi")

const publicData = {
  pubKeys: [
    Buffer.from(
      "03846f34fdb2345f4bf932cb4b7d278fb3af24f44224fb52ae551781c3a3cad68a",
      "hex"
    ),
    Buffer.from(
      "02cd836b1d42c51d80cef695a14502c21d2c3c644bc82f6a7052eb29247cf61f4f",
      "hex"
    ),
    Buffer.from(
      "03b8c1765111002f09ba35c468fab273798a9058d1f8a4e276f45a1f1481dd0bdb",
      "hex"
    )
  ],
  message: BITBOX.Schnorr.hash(Buffer.from("muSig is awesome!", "utf8")),
  pubKeyHash: null,
  pubKeyCombined: null,
  commitments: [],
  nonces: [],
  nonceCombined: null,
  partialSignatures: [],
  signature: null
}

// data only known by the individual party, these values are never shared
// between the signers!
const signerPrivateData = [
  // signer 1
  {
    privateKey: BigInteger.fromHex(
      "add2b25e2d356bec3770305391cbc80cab3a40057ad836bcb49ef3eed74a3fee"
    ),
    session: null
  },
  // signer 2
  {
    privateKey: BigInteger.fromHex(
      "0a1645eef5a10e1f5011269abba9fd85c4f0cc70820d6f102fb7137f2988ad78"
    ),
    session: null
  },
  // signer 3
  {
    privateKey: BigInteger.fromHex(
      "2031e7fed15c770519707bb092a6337215530e921ccea42030c15d86e8eaf0b8"
    ),
    session: null
  }
]

// -----------------------------------------------------------------------
// Step 1: Combine the public keys
// The public keys P_i are combined into the combined public key P.
// This can be done by every signer individually or by the initializing
// party and then be distributed to every participant.
// -----------------------------------------------------------------------
publicData.pubKeyHash = muSig.computeEll(publicData.pubKeys)
publicData.pubKeyCombined = muSig.pubKeyCombine(
  publicData.pubKeys,
  publicData.pubKeyHash
)

// -----------------------------------------------------------------------
// Step 2: Create the private signing session
// Each signing party does this in private. The session ID *must* be
// unique for every call to sessionInitialize, otherwise it's trivial for
// an attacker to extract the secret key!
// -----------------------------------------------------------------------
signerPrivateData.forEach((data, idx) => {
  const sessionId = randomBuffer(32) // must never be reused between sessions!
  data.session = muSig.sessionInitialize(
    sessionId,
    data.privateKey,
    publicData.message,
    publicData.pubKeyCombined,
    publicData.pubKeyHash,
    idx
  )
})
const signerSession = signerPrivateData[0].session

// -----------------------------------------------------------------------
// Step 3: Exchange commitments (communication round 1)
// The signers now exchange the commitments H(R_i). This is simulated here
// by copying the values from the private data to public data array.
// -----------------------------------------------------------------------
for (let i = 0; i < publicData.pubKeys.length; i++) {
  publicData.commitments[i] = signerPrivateData[i].session.commitment
}

// -----------------------------------------------------------------------
// Step 4: Get nonces (communication round 2)
// Now that everybody has commited to the session, the nonces (R_i) can be
// exchanged. Again, this is simulated by copying.
// -----------------------------------------------------------------------
for (let i = 0; i < publicData.pubKeys.length; i++) {
  publicData.nonces[i] = signerPrivateData[i].session.nonce
}

// -----------------------------------------------------------------------
// Step 5: Combine nonces
// The nonces can now be combined into R. Each participant should do this
// and keep track of whether the nonce was negated or not. This is needed
// for the later steps.
// -----------------------------------------------------------------------
publicData.nonceCombined = muSig.sessionNonceCombine(
  signerSession,
  publicData.nonces
)
signerPrivateData.forEach(
  data => (data.session.nonceIsNegated = signerSession.nonceIsNegated)
)

// -----------------------------------------------------------------------
// Step 6: Generate partial signatures
// Every participant can now create their partial signature s_i over the
// given message.
// -----------------------------------------------------------------------
signerPrivateData.forEach(data => {
  data.session.partialSignature = muSig.partialSign(
    data.session,
    publicData.message,
    publicData.nonceCombined,
    publicData.pubKeyCombined
  )
})

// -----------------------------------------------------------------------
// Step 7: Exchange partial signatures (communication round 3)
// The partial signature of each signer is exchanged with the other
// participants. Simulated here by copying.
// -----------------------------------------------------------------------
for (let i = 0; i < publicData.pubKeys.length; i++) {
  publicData.partialSignatures[i] =
    signerPrivateData[i].session.partialSignature
}

// -----------------------------------------------------------------------
// Step 8: Verify individual partial signatures
// Every participant should verify the partial signatures received by the
// other participants.
// -----------------------------------------------------------------------
for (let i = 0; i < publicData.pubKeys.length; i++) {
  muSig.partialSigVerify(
    signerSession,
    publicData.partialSignatures[i],
    publicData.nonceCombined,
    i,
    publicData.pubKeys[i],
    publicData.nonces[i]
  )
}

// -----------------------------------------------------------------------
// Step 9: Combine partial signatures
// Finally, the partial signatures can be combined into the full signature
// (s, R) that can be verified against combined public key P.
// -----------------------------------------------------------------------
publicData.signature = muSig.partialSigCombine(
  publicData.nonceCombined,
  publicData.partialSignatures
)

// -----------------------------------------------------------------------
// Step 10: Verify signature
// The resulting signature can now be verified as a normal Schnorr
// signature (s, R) over the message m and public key P.
// -----------------------------------------------------------------------
BITBOX.Schnorr.verify(
  publicData.pubKeyCombined,
  publicData.message,
  publicData.signature
)