Inside Bitcoin
Opening the selected file…
Inside Bitcoin
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
1/***********************************************************************2* Copyright (c) 2015 Pieter Wuille *3* Distributed under the MIT software license, see the accompanying *4* file COPYING or https://www.opensource.org/licenses/mit-license.php.*5***********************************************************************/7#include <string.h>9#include "lax_der_parsing.h"11int ecdsa_signature_parse_der_lax(const secp256k1_context* ctx, secp256k1_ecdsa_signature* sig, const unsigned char *input, size_t inputlen) {12size_t rpos, rlen, spos, slen;13size_t pos = 0;14size_t lenbyte;15unsigned char tmpsig[64] = {0};16int overflow = 0;18/* Hack to initialize sig with a correctly-parsed but invalid signature. */19secp256k1_ecdsa_signature_parse_compact(ctx, sig, tmpsig);21/* Sequence tag byte */22if (pos == inputlen || input[pos] != 0x30) {23return 0;24}25pos++;27/* Sequence length bytes */28if (pos == inputlen) {29return 0;30}31lenbyte = input[pos++];32if (lenbyte & 0x80) {33lenbyte -= 0x80;34if (lenbyte > inputlen - pos) {35return 0;36}37pos += lenbyte;38}40/* Integer tag byte for R */41if (pos == inputlen || input[pos] != 0x02) {42return 0;43}44pos++;46/* Integer length for R */47if (pos == inputlen) {48return 0;49}50lenbyte = input[pos++];51if (lenbyte & 0x80) {52lenbyte -= 0x80;53if (lenbyte > inputlen - pos) {54return 0;55}56while (lenbyte > 0 && input[pos] == 0) {57pos++;58lenbyte--;59}60if (lenbyte >= sizeof(size_t)) {61return 0;62}63rlen = 0;64while (lenbyte > 0) {65rlen = (rlen << 8) + input[pos];66pos++;67lenbyte--;68}69} else {70rlen = lenbyte;71}72if (rlen > inputlen - pos) {73return 0;74}75rpos = pos;76pos += rlen;78/* Integer tag byte for S */79if (pos == inputlen || input[pos] != 0x02) {80return 0;81}82pos++;84/* Integer length for S */85if (pos == inputlen) {86return 0;87}88lenbyte = input[pos++];89if (lenbyte & 0x80) {90lenbyte -= 0x80;91if (lenbyte > inputlen - pos) {92return 0;93}94while (lenbyte > 0 && input[pos] == 0) {95pos++;96lenbyte--;97}98if (lenbyte >= sizeof(size_t)) {99return 0;100}101slen = 0;102while (lenbyte > 0) {103slen = (slen << 8) + input[pos];104pos++;105lenbyte--;106}107} else {108slen = lenbyte;109}110if (slen > inputlen - pos) {111return 0;112}113spos = pos;115/* Ignore leading zeroes in R */116while (rlen > 0 && input[rpos] == 0) {117rlen--;118rpos++;119}120/* Copy R value */121if (rlen > 32) {122overflow = 1;123} else if (rlen) {124memcpy(tmpsig + 32 - rlen, input + rpos, rlen);125}127/* Ignore leading zeroes in S */128while (slen > 0 && input[spos] == 0) {129slen--;130spos++;131}132/* Copy S value */133if (slen > 32) {134overflow = 1;135} else if (slen) {136memcpy(tmpsig + 64 - slen, input + spos, slen);137}139if (!overflow) {140overflow = !secp256k1_ecdsa_signature_parse_compact(ctx, sig, tmpsig);141}142if (overflow) {143memset(tmpsig, 0, 64);144secp256k1_ecdsa_signature_parse_compact(ctx, sig, tmpsig);145}146return 1;147}
Independent explanations by MyBitcoinExplorer. Not affiliated with or endorsed by Bitcoin Core. Guides are educational and do not replace the source or its tests.
Bitcoin Core source © its contributors, distributed under the MIT license. Original notices and bundled third-party licenses are retained in the source tree.