csecp256k1

Haskell FFI bindings to bitcoin-core/secp256k1 (docs.ppad.tech/csecp256k1).
git clone git://git.ppad.tech/csecp256k1.git
Log | Files | Refs | README | LICENSE

lax_der_parsing.c (3689B)


      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  ***********************************************************************/
      6 
      7 #include <string.h>
      8 
      9 #include "lax_der_parsing.h"
     10 
     11 int haskellsecp256k1_v0_1_0_ecdsa_signature_parse_der_lax(const haskellsecp256k1_v0_1_0_context* ctx, haskellsecp256k1_v0_1_0_ecdsa_signature* sig, const unsigned char *input, size_t inputlen) {
     12     size_t rpos, rlen, spos, slen;
     13     size_t pos = 0;
     14     size_t lenbyte;
     15     unsigned char tmpsig[64] = {0};
     16     int overflow = 0;
     17 
     18     /* Hack to initialize sig with a correctly-parsed but invalid signature. */
     19     haskellsecp256k1_v0_1_0_ecdsa_signature_parse_compact(ctx, sig, tmpsig);
     20 
     21     /* Sequence tag byte */
     22     if (pos == inputlen || input[pos] != 0x30) {
     23         return 0;
     24     }
     25     pos++;
     26 
     27     /* Sequence length bytes */
     28     if (pos == inputlen) {
     29         return 0;
     30     }
     31     lenbyte = input[pos++];
     32     if (lenbyte & 0x80) {
     33         lenbyte -= 0x80;
     34         if (lenbyte > inputlen - pos) {
     35             return 0;
     36         }
     37         pos += lenbyte;
     38     }
     39 
     40     /* Integer tag byte for R */
     41     if (pos == inputlen || input[pos] != 0x02) {
     42         return 0;
     43     }
     44     pos++;
     45 
     46     /* Integer length for R */
     47     if (pos == inputlen) {
     48         return 0;
     49     }
     50     lenbyte = input[pos++];
     51     if (lenbyte & 0x80) {
     52         lenbyte -= 0x80;
     53         if (lenbyte > inputlen - pos) {
     54             return 0;
     55         }
     56         while (lenbyte > 0 && input[pos] == 0) {
     57             pos++;
     58             lenbyte--;
     59         }
     60         if (lenbyte >= sizeof(size_t)) {
     61             return 0;
     62         }
     63         rlen = 0;
     64         while (lenbyte > 0) {
     65             rlen = (rlen << 8) + input[pos];
     66             pos++;
     67             lenbyte--;
     68         }
     69     } else {
     70         rlen = lenbyte;
     71     }
     72     if (rlen > inputlen - pos) {
     73         return 0;
     74     }
     75     rpos = pos;
     76     pos += rlen;
     77 
     78     /* Integer tag byte for S */
     79     if (pos == inputlen || input[pos] != 0x02) {
     80         return 0;
     81     }
     82     pos++;
     83 
     84     /* Integer length for S */
     85     if (pos == inputlen) {
     86         return 0;
     87     }
     88     lenbyte = input[pos++];
     89     if (lenbyte & 0x80) {
     90         lenbyte -= 0x80;
     91         if (lenbyte > inputlen - pos) {
     92             return 0;
     93         }
     94         while (lenbyte > 0 && input[pos] == 0) {
     95             pos++;
     96             lenbyte--;
     97         }
     98         if (lenbyte >= sizeof(size_t)) {
     99             return 0;
    100         }
    101         slen = 0;
    102         while (lenbyte > 0) {
    103             slen = (slen << 8) + input[pos];
    104             pos++;
    105             lenbyte--;
    106         }
    107     } else {
    108         slen = lenbyte;
    109     }
    110     if (slen > inputlen - pos) {
    111         return 0;
    112     }
    113     spos = pos;
    114 
    115     /* Ignore leading zeroes in R */
    116     while (rlen > 0 && input[rpos] == 0) {
    117         rlen--;
    118         rpos++;
    119     }
    120     /* Copy R value */
    121     if (rlen > 32) {
    122         overflow = 1;
    123     } else if (rlen) {
    124         memcpy(tmpsig + 32 - rlen, input + rpos, rlen);
    125     }
    126 
    127     /* Ignore leading zeroes in S */
    128     while (slen > 0 && input[spos] == 0) {
    129         slen--;
    130         spos++;
    131     }
    132     /* Copy S value */
    133     if (slen > 32) {
    134         overflow = 1;
    135     } else if (slen) {
    136         memcpy(tmpsig + 64 - slen, input + spos, slen);
    137     }
    138 
    139     if (!overflow) {
    140         overflow = !haskellsecp256k1_v0_1_0_ecdsa_signature_parse_compact(ctx, sig, tmpsig);
    141     }
    142     if (overflow) {
    143         memset(tmpsig, 0, 64);
    144         haskellsecp256k1_v0_1_0_ecdsa_signature_parse_compact(ctx, sig, tmpsig);
    145     }
    146     return 1;
    147 }
    148