function signatureDerToP1363(derSignature) {

  const derSignatureHex = arrBufToHex(derSignature);

  /* 
   * ASN.1 DER format for signature -
   *   Ecdsa-Sig-Value  ::=  SEQUENCE  {
   *     r     INTEGER,
   *     s     INTEGER  }
   * (from https://datatracker.ietf.org/doc/html/rfc3278#section-8.2,
   *  https://datatracker.ietf.org/doc/html/rfc3279#section-2.2.3)
   * 
   * This is represented in hexa-decimal string as -
   * 
   *   Offset          Value   Bytes   Description
   *   ------          -----   -----   -------------------------------
   *   0               0x30    2       SEQUENCE header
   *   2               Size    2       Size of the SEQUENCE
   *   4               0x02    2       INTEGER type
   *   6               Size    2       Size of the INTEGER "r" = size_r
   *   8               Bytes   size_r  Bytes of the INTEGER "r" (big endian)
   *   8+(size_r*2)    0x02    2       INTEGER type
   *   8+(size_r*2)+2  Size    2       Size of the INTEGER "s" = size_s
   *   8+(size_r*2)+4  Bytes   size_s  Bytes of the INTEGER "s" (big endian)
   */

  if (parseInt(derSignatureHex.substr(0, 2), 16) != 0x30) {
    throw "Expected SEQUENCE at start of signature";
  }

  if (parseInt(derSignatureHex.substr(4, 2), 16) != 0x02) {
    throw "Expected INTEGER as first value of sequence";
  }

  // Parse size of "r".
  const rSizeInHexChars = parseInt(derSignatureHex.substr(6, 2), 16) * 2;
  // Get "r".
  let r = derSignatureHex.substr(8, rSizeInHexChars);

  if (parseInt(derSignatureHex.substr(8 + rSizeInHexChars, 2), 16) != 0x02) {
    throw "Expected INTEGER as second value of sequence";
  }

  // Parse size of "s".
  const sSizeInHexChars = parseInt(derSignatureHex.substr(8 + rSizeInHexChars + 2, 2), 16) * 2;
  // Get "s".
  let s = derSignatureHex.substr(8 + rSizeInHexChars + 4, sSizeInHexChars);

  // Integers might be larger than 32 bytes in ASN.1 (because negative integers need to have a prefix of 0).
  // Integers must be exactly 32 bytes in P1363 (padded by zeros).

  // Trim all leading zeros from r and s, and pad to 32 bytes.
  r = trimHexLeadingZeros(r).padStart(32*2, "0");
  s = trimHexLeadingZeros(s).padStart(32*2, "0");

  // Make sure the resulting strings are exactly 32 bytes long.
  if ((r.length != 32*2) || (s.length != 32*2)) {
    throw "r or s are not of the expected size";
  }

  // Concatenate r and s together - that's P1363 format.
  return hexToUint8Arr(r + s);
}
// P1363 format is used by WebCrypto.
P1363 format is used by WebCrypto.
P1363 format is used by WebCrypto .
function signatureDerToP1363(derSignature) {
  const derSignatureHex = arrBufToHex(derSignature);
  if (parseInt(derSignatureHex.substr(0, 2), 16) != 0x30) {
    throw "Expected SEQUENCE at start of signature";
  }
  if (parseInt(derSignatureHex.substr(4, 2), 16) != 0x02) {
    throw "Expected INTEGER as first value of sequence";
  }
  const rSizeInHexChars = parseInt(derSignatureHex.substr(6, 2), 16) * 2;
  let r = derSignatureHex.substr(8, rSizeInHexChars);
  if (parseInt(derSignatureHex.substr(8 + rSizeInHexChars, 2), 16) != 0x02) {
    throw "Expected INTEGER as second value of sequence";
  }
  const sSizeInHexChars = parseInt(derSignatureHex.substr(8 + rSizeInHexChars + 2, 2), 16) * 2;
  let s = derSignatureHex.substr(8 + rSizeInHexChars + 4, sSizeInHexChars);
  r = trimHexLeadingZeros(r).padStart(32*2, "0");
  s = trimHexLeadingZeros(s).padStart(32*2, "0");
  if ((r.length != 32*2) || (s.length != 32*2)) {
    throw "r or s are not of the expected size";
  }
  return hexToUint8Arr(r + s);
}
function signatureDerToP1363 ( derSignature ) { const derSignatureHex = arrBufToHex ( derSignature ) ; if ( parseInt ( derSignatureHex . substr ( 0 , 2 ) , 16 ) != 0x30 ) { throw "Expected SEQUENCE at start of signature" ; } if ( parseInt ( derSignatureHex . substr ( 4 , 2 ) , 16 ) != 0x02 ) { throw "Expected INTEGER as first value of sequence" ; } const rSizeInHexChars = parseInt ( derSignatureHex . substr ( 6 , 2 ) , 16 ) * 2 ; let r = derSignatureHex . substr ( 8 , rSizeInHexChars ) ; if ( parseInt ( derSignatureHex . substr ( 8 + rSizeInHexChars , 2 ) , 16 ) != 0x02 ) { throw "Expected INTEGER as second value of sequence" ; } const sSizeInHexChars = parseInt ( derSignatureHex . substr ( 8 + rSizeInHexChars + 2 , 2 ) , 16 ) * 2 ; let s = derSignatureHex . substr ( 8 + rSizeInHexChars + 4 , sSizeInHexChars ) ; r = trimHexLeadingZeros ( r ) . padStart ( 32 * 2 , "0" ) ; s = trimHexLeadingZeros ( s ) . padStart ( 32 * 2 , "0" ) ; if ( ( r . length != 32 * 2 ) || ( s . length != 32 * 2 ) ) { throw "r or s are not of the expected size" ; } return hexToUint8Arr ( r + s ) ; }
P1363 format is used by WebCrypto.
P1363 format is used by WebCrypto .
/* 
   * ASN.1 DER format for signature -
   *   Ecdsa-Sig-Value  ::=  SEQUENCE  {
   *     r     INTEGER,
   *     s     INTEGER  }
   * (from https://datatracker.ietf.org/doc/html/rfc3278#section-8.2,
   *  https://datatracker.ietf.org/doc/html/rfc3279#section-2.2.3)
   * 
   * This is represented in hexa-decimal string as -
   * 
   *   Offset          Value   Bytes   Description
   *   ------          -----   -----   -------------------------------
   *   0               0x30    2       SEQUENCE header
   *   2               Size    2       Size of the SEQUENCE
   *   4               0x02    2       INTEGER type
   *   6               Size    2       Size of the INTEGER "r" = size_r
   *   8               Bytes   size_r  Bytes of the INTEGER "r" (big endian)
   *   8+(size_r*2)    0x02    2       INTEGER type
   *   8+(size_r*2)+2  Size    2       Size of the INTEGER "s" = size_s
   *   8+(size_r*2)+4  Bytes   size_s  Bytes of the INTEGER "s" (big endian)
   */ // Parse size of "r". // Get "r". // Parse size of "s". // Get "s". // Integers might be larger than 32 bytes in ASN.1 (because negative integers need to have a prefix of 0). // Integers must be exactly 32 bytes in P1363 (padded by zeros). // Trim all leading zeros from r and s, and pad to 32 bytes. // Make sure the resulting strings are exactly 32 bytes long. // Concatenate r and s together - that's P1363 format.