Add "lax DER" support; bump major version number for recent build system changes

This commit is contained in:
Andrew Poelstra 2015-10-26 12:59:40 -05:00
parent e7ca836c2b
commit 8e984c5912
5 changed files with 73 additions and 17 deletions

View File

@ -1,7 +1,7 @@
[package] [package]
name = "secp256k1" name = "secp256k1"
version = "0.3.3" version = "0.4.0"
authors = [ "Dawid Ciężarkiewicz <dpc@ucore.info>", authors = [ "Dawid Ciężarkiewicz <dpc@ucore.info>",
"Andrew Poelstra <apoelstra@wpsoftware.net>" ] "Andrew Poelstra <apoelstra@wpsoftware.net>" ]
license = "CC0-1.0" license = "CC0-1.0"

View File

@ -24,21 +24,25 @@
extern crate gcc; extern crate gcc;
fn main() { fn main() {
gcc::Config::new() let mut base_config = gcc::Config::new();
.file("depend/secp256k1/src/secp256k1.c") base_config.include("depend/secp256k1/")
.include("depend/secp256k1/") .include("depend/secp256k1/src")
.include("depend/secp256k1/src") .flag("-g")
// TODO these three should be changed to use libgmp, at least until secp PR 290 is merged // TODO these three should be changed to use libgmp, at least until secp PR 290 is merged
.define("USE_NUM_NONE", Some("1")) .define("USE_NUM_NONE", Some("1"))
.define("USE_FIELD_INV_BUILTIN", Some("1")) .define("USE_FIELD_INV_BUILTIN", Some("1"))
.define("USE_SCALAR_INV_BUILTIN", Some("1")) .define("USE_SCALAR_INV_BUILTIN", Some("1"))
// TODO these should use 64-bit variants on 64-bit systems // TODO these should use 64-bit variants on 64-bit systems
.define("USE_FIELD_10X26", Some("1")) .define("USE_FIELD_10X26", Some("1"))
.define("USE_SCALAR_8X32", Some("1")) .define("USE_SCALAR_8X32", Some("1"))
.define("USE_ENDOMORPHISM", Some("1")) .define("USE_ENDOMORPHISM", Some("1"))
// These all are OK. // These all are OK.
.define("ENABLE_MODULE_ECDH", Some("1")) .define("ENABLE_MODULE_ECDH", Some("1"))
.define("ENABLE_MODULE_RECOVERY", Some("1")) .define("ENABLE_MODULE_RECOVERY", Some("1"));
.compile("libsecp256k1.a");
// secp256k1
base_config.file("depend/secp256k1/src/laxder_shim.c")
.file("depend/secp256k1/src/secp256k1.c")
.compile("libsecp256k1.a");
} }

View File

@ -0,0 +1,21 @@
/* Bitcoin secp256k1 bindings
* Written in 2015 by
* Andrew Poelstra
*
* To the extent possible under law, the author(s) have dedicated all
* copyright and related and neighboring rights to this software to
* the public domain worldwide. This software is distributed without
* any warranty.
*
* You should have received a copy of the CC0 Public Domain Dedication
* along with this software.
* If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
*/
#include "contrib/lax_der_parsing.h"
int secp256k1_ecdsa_signature_parse_der_lax_(const secp256k1_context* ctx, secp256k1_ecdsa_signature* sig, const unsigned char *input, size_t inputlen) {
return secp256k1_ecdsa_signature_parse_der_lax(ctx, sig, input, inputlen);
}

View File

@ -154,6 +154,10 @@ extern "C" {
input: *const c_uchar, in_len: size_t) input: *const c_uchar, in_len: size_t)
-> c_int; -> c_int;
pub fn secp256k1_ecdsa_signature_parse_der_lax_(cx: Context, sig: *mut Signature,
input: *const c_uchar, in_len: size_t)
-> c_int;
pub fn secp256k1_ecdsa_signature_serialize_der(cx: Context, output: *const c_uchar, pub fn secp256k1_ecdsa_signature_serialize_der(cx: Context, output: *const c_uchar,
out_len: *const size_t, sig: *const Signature) out_len: *const size_t, sig: *const Signature)
-> c_int; -> c_int;

View File

@ -99,6 +99,22 @@ impl Signature {
} }
} }
/// Converts a "lax DER"-encoded byte slice to a signature. This is basically
/// only useful for validating signatures in the Bitcoin blockchain from before
/// 2016. It should never be used in new applications. This library does not
/// support serializing to this "format"
pub fn from_der_lax(secp: &Secp256k1, data: &[u8]) -> Result<Signature, Error> {
unsafe {
let mut ret = ffi::Signature::blank();
if ffi::secp256k1_ecdsa_signature_parse_der_lax_(secp.ctx, &mut ret,
data.as_ptr(), data.len() as libc::size_t) == 1 {
Ok(Signature(ret))
} else {
Err(Error::InvalidSignature)
}
}
}
/// Obtains a raw pointer suitable for use with FFI functions /// Obtains a raw pointer suitable for use with FFI functions
#[inline] #[inline]
pub fn as_ptr(&self) -> *const ffi::Signature { pub fn as_ptr(&self) -> *const ffi::Signature {
@ -484,6 +500,7 @@ impl Secp256k1 {
mod tests { mod tests {
use rand::{Rng, thread_rng}; use rand::{Rng, thread_rng};
use std::ptr; use std::ptr;
use serialize::hex::FromHex;
use key::{SecretKey, PublicKey}; use key::{SecretKey, PublicKey};
use super::constants; use super::constants;
@ -491,6 +508,8 @@ mod tests {
use super::Error::{InvalidMessage, InvalidPublicKey, IncorrectSignature, InvalidSignature, use super::Error::{InvalidMessage, InvalidPublicKey, IncorrectSignature, InvalidSignature,
IncapableContext}; IncapableContext};
macro_rules! hex (($hex:expr) => ($hex.from_hex().unwrap()));
#[test] #[test]
fn capabilities() { fn capabilities() {
let none = Secp256k1::with_caps(ContextFlag::None); let none = Secp256k1::with_caps(ContextFlag::None);
@ -610,6 +629,14 @@ mod tests {
} }
} }
#[test]
fn signature_lax_der() {
let secp = Secp256k1::without_caps();
let sig = hex!("304402204c2dd8a9b6f8d425fcd8ee9a20ac73b619906a6367eac6cb93e70375225ec0160220356878eff111ff3663d7e6bf08947f94443845e0dcc54961664d922f7660b80c01");
assert!(Signature::from_der(&secp, &sig[..]).is_err());
assert!(Signature::from_der_lax(&secp, &sig[..]).is_ok());
}
#[test] #[test]
fn sign_and_verify() { fn sign_and_verify() {
let mut s = Secp256k1::new(); let mut s = Secp256k1::new();