From 0b3ab8d5e9e19fc9b259dcb2a061f6c765957427 Mon Sep 17 00:00:00 2001 From: UdjinM6 Date: Wed, 28 Jun 2023 23:37:52 +0300 Subject: [PATCH 1/3] Revert "build: stop tracking cmake dependency relic_conf.h.in" This reverts commit a82d0efcd039e94cc75339dcc84beeadf415680e. --- .../depends/relic/include/relic_conf.h.in | 717 ++++++++++++++++++ 1 file changed, 717 insertions(+) create mode 100644 src/dashbls/depends/relic/include/relic_conf.h.in diff --git a/src/dashbls/depends/relic/include/relic_conf.h.in b/src/dashbls/depends/relic/include/relic_conf.h.in new file mode 100644 index 0000000000..7db6f5b509 --- /dev/null +++ b/src/dashbls/depends/relic/include/relic_conf.h.in @@ -0,0 +1,717 @@ +/* + * RELIC is an Efficient LIbrary for Cryptography + * Copyright (c) 2009 RELIC Authors + * + * This file is part of RELIC. RELIC is legal property of its developers, + * whose names are not listed here. Please refer to the COPYRIGHT file + * for contact information. + * + * RELIC is free software; you can redistribute it and/or modify it under the + * terms of the version 2.1 (or later) of the GNU Lesser General Public License + * as published by the Free Software Foundation; or version 2.0 of the Apache + * License as published by the Apache Software Foundation. See the LICENSE files + * for more details. + * + * RELIC is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the LICENSE files for more details. + * + * You should have received a copy of the GNU Lesser General Public or the + * Apache License along with RELIC. If not, see + * or . + */ + +/** + * @file + * + * Project configuration. + * + * @version $Id: relic_conf.h.in 45 2009-07-04 23:45:48Z dfaranha $ + * @ingroup relic + */ + +#ifndef RLC_CONF_H +#define RLC_CONF_H + +/** Project version. */ +#define RLC_VERSION "@VERSION@" + +/** Debugging support. */ +#cmakedefine DEBUG +/** Profiling support. */ +#cmakedefine PROFL +/** Error handling support. */ +#cmakedefine CHECK +/** Verbose error messages. */ +#cmakedefine VERBS +/** Build with overhead estimation. */ +#cmakedefine OVERH +/** Build documentation. */ +#cmakedefine DOCUM +/** Build only the selected algorithms. */ +#cmakedefine STRIP +/** Build with printing disabled. */ +#cmakedefine QUIET +/** Build with colored output. */ +#cmakedefine COLOR +/** Build with big-endian support. */ +#cmakedefine BIGED +/** Build shared library. */ +#cmakedefine SHLIB +/** Build static library. */ +#cmakedefine STLIB + +/** Number of times each test is ran. */ +#define TESTS @TESTS@ +/** Number of times each benchmark is ran. */ +#define BENCH @BENCH@ +/** Number of available cores. */ +#define CORES @CORES@ + +/** Atmel AVR ATMega128 8-bit architecture. */ +#define AVR 1 +/** MSP430 16-bit architecture. */ +#define MSP 2 +/** ARM 32-bit architecture. */ +#define ARM 3 +/** Intel x86-compatible 32-bit architecture. */ +#define X86 4 +/** AMD64-compatible 64-bit architecture. */ +#define X64 5 +/** Architecture. */ +#cmakedefine ARCH @ARCH@ + +/** Size of word in this architecture. */ +#define WSIZE @WSIZE@ + +/** Byte boundary to align digit vectors. */ +#define ALIGN @ALIGN@ + +/** Build multiple precision integer module. */ +#cmakedefine WITH_BN +/** Build prime field module. */ +#cmakedefine WITH_FP +/** Build prime field extension module. */ +#cmakedefine WITH_FPX +/** Build binary field module. */ +#cmakedefine WITH_FB +/** Build prime elliptic curve module. */ +#cmakedefine WITH_EP +/** Build prime field extension elliptic curve module. */ +#cmakedefine WITH_EPX +/** Build binary elliptic curve module. */ +#cmakedefine WITH_EB +/** Build elliptic Edwards curve module. */ +#cmakedefine WITH_ED +/** Build elliptic curve cryptography module. */ +#cmakedefine WITH_EC +/** Build pairings over prime curves module. */ +#cmakedefine WITH_PP +/** Build pairing-based cryptography module. */ +#cmakedefine WITH_PC +/** Build block ciphers. */ +#cmakedefine WITH_BC +/** Build hash functions. */ +#cmakedefine WITH_MD +/** Build cryptographic protocols. */ +#cmakedefine WITH_CP +/** Build Multi-party computation primitives. */ +#cmakedefine WITH_MPC + +/** Easy C-only backend. */ +#define EASY 1 +/** GMP backend. */ +#define GMP 2 +/** GMP constant-time backend. */ +#define GMP_SEC 3 +/** Arithmetic backend. */ +#define ARITH @ARITH@ + +/** Required precision in bits. */ +#define BN_PRECI @BN_PRECI@ +/** A multiple precision integer can store w words. */ +#define SINGLE 0 +/** A multiple precision integer can store the result of an addition. */ +#define CARRY 1 +/** A multiple precision integer can store the result of a multiplication. */ +#define DOUBLE 2 +/** Effective size of a multiple precision integer. */ +#define BN_MAGNI @BN_MAGNI@ +/** Number of Karatsuba steps. */ +#define BN_KARAT @BN_KARAT@ + +/** Schoolbook multiplication. */ +#define BASIC 1 +/** Comba multiplication. */ +#define COMBA 2 +/** Chosen multiple precision multiplication method. */ +#define BN_MUL @BN_MUL@ + +/** Schoolbook squaring. */ +#define BASIC 1 +/** Comba squaring. */ +#define COMBA 2 +/** Reuse multiplication for squaring. */ +#define MULTP 4 +/** Chosen multiple precision multiplication method. */ +#define BN_SQR @BN_SQR@ + +/** Division modular reduction. */ +#define BASIC 1 +/** Barrett modular reduction. */ +#define BARRT 2 +/** Montgomery modular reduction. */ +#define MONTY 3 +/** Pseudo-Mersenne modular reduction. */ +#define PMERS 4 +/** Chosen multiple precision modular reduction method. */ +#define BN_MOD @BN_MOD@ + +/** Binary modular exponentiation. */ +#define BASIC 1 +/** Sliding window modular exponentiation. */ +#define SLIDE 2 +/** Montgomery powering ladder. */ +#define MONTY 3 +/** Chosen multiple precision modular exponentiation method. */ +#define BN_MXP @BN_MXP@ + +/** Basic Euclidean GCD Algorithm. */ +#define BASIC 1 +/** Lehmer's fast GCD Algorithm. */ +#define LEHME 2 +/** Stein's binary GCD Algorithm. */ +#define STEIN 3 +/** Chosen multiple precision greatest common divisor method. */ +#define BN_GCD @BN_GCD@ + +/** Basic prime generation. */ +#define BASIC 1 +/** Safe prime generation. */ +#define SAFEP 2 +/** Strong prime generation. */ +#define STRON 3 +/** Chosen prime generation algorithm. */ +#define BN_GEN @BN_GEN@ + +/** Multiple precision arithmetic method */ +#define BN_METHD "@BN_METHD@" + +/** Prime field size in bits. */ +#define FP_PRIME @FP_PRIME@ +/** Number of Karatsuba steps. */ +#define FP_KARAT @FP_KARAT@ +/** Prefer Pseudo-Mersenne primes over random primes. */ +#cmakedefine FP_PMERS +/** Use -1 as quadratic non-residue. */ +#cmakedefine FP_QNRES +/** Width of window processing for exponentiation methods. */ +#define FP_WIDTH @FP_WIDTH@ + +/** Schoolbook addition. */ +#define BASIC 1 +/** Integrated modular addtion. */ +#define INTEG 3 +/** Chosen prime field multiplication method. */ +#define FP_ADD @FP_ADD@ + +/** Schoolbook multiplication. */ +#define BASIC 1 +/** Comba multiplication. */ +#define COMBA 2 +/** Integrated modular multiplication. */ +#define INTEG 3 +/** Chosen prime field multiplication method. */ +#define FP_MUL @FP_MUL@ + +/** Schoolbook squaring. */ +#define BASIC 1 +/** Comba squaring. */ +#define COMBA 2 +/** Integrated modular squaring. */ +#define INTEG 3 +/** Reuse multiplication for squaring. */ +#define MULTP 4 +/** Chosen prime field multiplication method. */ +#define FP_SQR @FP_SQR@ + +/** Division-based reduction. */ +#define BASIC 1 +/** Fast reduction modulo special form prime. */ +#define QUICK 2 +/** Montgomery modular reduction. */ +#define MONTY 3 +/** Chosen prime field reduction method. */ +#define FP_RDC @FP_RDC@ + +/** Inversion by Fermat's Little Theorem. */ +#define BASIC 1 +/** Binary inversion. */ +#define BINAR 2 +/** Integrated modular multiplication. */ +#define MONTY 3 +/** Extended Euclidean algorithm. */ +#define EXGCD 4 +/** Constant-time inversion by Bernstein-Yang division steps. */ +#define DIVST 5 +/** Use implementation provided by the lower layer. */ +#define LOWER 8 +/** Chosen prime field inversion method. */ +#define FP_INV @FP_INV@ + +/** Binary modular exponentiation. */ +#define BASIC 1 +/** Sliding window modular exponentiation. */ +#define SLIDE 2 +/** Constant-time Montgomery powering ladder. */ +#define MONTY 3 +/** Chosen multiple precision modular exponentiation method. */ +#define FP_EXP @FP_EXP@ + +/** Prime field arithmetic method */ +#define FP_METHD "@FP_METHD@" + +/** Basic quadratic extension field arithmetic. */ +#define BASIC 1 +/** Integrated extension field arithmetic. */ +#define INTEG 3 +/* Chosen extension field arithmetic method. */ +#define FPX_QDR @FPX_QDR@ + +/** Basic cubic extension field arithmetic. */ +#define BASIC 1 +/** Integrated extension field arithmetic. */ +#define INTEG 3 +/* Chosen extension field arithmetic method. */ +#define FPX_CBC @FPX_CBC@ + +/** Basic quadratic extension field arithmetic. */ +#define BASIC 1 +/** Lazy-reduced extension field arithmetic. */ +#define LAZYR 2 +/* Chosen extension field arithmetic method. */ +#define FPX_RDC @FPX_RDC@ + +/** Prime extension field arithmetic method */ +#define FPX_METHD "@FPX_METHD@" + +/** Irreducible polynomial size in bits. */ +#define FB_POLYN @FB_POLYN@ +/** Number of Karatsuba steps. */ +#define FB_KARAT @FB_KARAT@ +/** Prefer trinomials over pentanomials. */ +#cmakedefine FB_TRINO +/** Prefer square-root friendly polynomials. */ +#cmakedefine FB_SQRTF +/** Precompute multiplication table for sqrt(z). */ +#cmakedefine FB_PRECO +/** Width of window processing for exponentiation methods. */ +#define FB_WIDTH @FB_WIDTH@ + +/** Shift-and-add multiplication. */ +#define BASIC 1 +/** Lopez-Dahab multiplication. */ +#define LODAH 2 +/** Integrated modular multiplication. */ +#define INTEG 3 +/** Chosen binary field multiplication method. */ +#define FB_MUL @FB_MUL@ + +/** Basic squaring. */ +#define BASIC 1 +/** Table-based squaring. */ +#define QUICK 2 +/** Integrated modular squaring. */ +#define INTEG 3 +/** Chosen binary field squaring method. */ +#define FB_SQR @FB_SQR@ + +/** Shift-and-add modular reduction. */ +#define BASIC 1 +/** Fast reduction modulo a trinomial or pentanomial. */ +#define QUICK 2 +/** Chosen binary field modular reduction method. */ +#define FB_RDC @FB_RDC@ + +/** Square root by repeated squaring. */ +#define BASIC 1 +/** Fast square root extraction. */ +#define QUICK 2 +/** Chosen binary field modular reduction method. */ +#define FB_SRT @FB_SRT@ + +/** Trace by repeated squaring. */ +#define BASIC 1 +/** Fast trace computation. */ +#define QUICK 2 +/** Chosen trace computation method. */ +#define FB_TRC @FB_TRC@ + +/** Solve by half-trace computation. */ +#define BASIC 1 +/** Solve with precomputed half-traces. */ +#define QUICK 2 +/** Chosen method to solve a quadratic equation. */ +#define FB_SLV @FB_SLV@ + +/** Inversion by Fermat's Little Theorem. */ +#define BASIC 1 +/** Binary inversion. */ +#define BINAR 2 +/** Almost inverse algorithm. */ +#define ALMOS 3 +/** Extended Euclidean algorithm. */ +#define EXGCD 4 +/** Itoh-Tsuji inversion. */ +#define ITOHT 5 +/** Hardware-friendly inversion by Brunner-Curiger-Hofstetter.*/ +#define BRUCH 6 +/** Constant-time version of almost inverse. */ +#define CTAIA 7 +/** Use implementation provided by the lower layer. */ +#define LOWER 8 +/** Chosen binary field inversion method. */ +#define FB_INV @FB_INV@ + +/** Binary modular exponentiation. */ +#define BASIC 1 +/** Sliding window modular exponentiation. */ +#define SLIDE 2 +/** Constant-time Montgomery powering ladder. */ +#define MONTY 3 +/** Chosen multiple precision modular exponentiation method. */ +#define FB_EXP @FB_EXP@ + +/** Iterated squaring/square-root by consecutive squaring/square-root. */ +#define BASIC 1 +/** Iterated squaring/square-root by table-based method. */ +#define QUICK 2 +/** Chosen method to solve a quadratic equation. */ +#define FB_ITR @FB_ITR@ + +/** Binary field arithmetic method */ +#define FB_METHD "@FB_METHD@" + +/** Support for ordinary curves. */ +#cmakedefine EP_PLAIN +/** Support for supersingular curves. */ +#cmakedefine EP_SUPER +/** Support for prime curves with efficient endormorphisms. */ +#cmakedefine EP_ENDOM +/** Use mixed coordinates. */ +#cmakedefine EP_MIXED +/** Build precomputation table for generator. */ +#cmakedefine EP_PRECO +/** Enable isogeny map for SSWU map-to-curve. */ +#cmakedefine EP_CTMAP +/** Width of precomputation table for fixed point methods. */ +#define EP_DEPTH @EP_DEPTH@ +/** Width of window processing for unknown point methods. */ +#define EP_WIDTH @EP_WIDTH@ + +/** Affine coordinates. */ +#define BASIC 1 +/** Projective coordinates. */ +#define PROJC 2 +/** Jacobian coordinates. */ +#define JACOB 3 +/** Chosen prime elliptic curve coordinate method. */ +#define EP_ADD @EP_ADD@ + +/** Binary point multiplication. */ +#define BASIC 1 +/** Sliding window. */ +#define SLIDE 2 +/** Montgomery powering ladder. */ +#define MONTY 3 +/** Left-to-right Width-w NAF. */ +#define LWNAF 4 +/** Left-to-right Width-w NAF. */ +#define LWREG 5 +/** Chosen prime elliptic curve point multiplication method. */ +#define EP_MUL @EP_MUL@ + +/** Binary point multiplication. */ +#define BASIC 1 +/** Single-table comb method. */ +#define COMBS 2 +/** Double-table comb method. */ +#define COMBD 3 +/** Left-to-right Width-w NAF. */ +#define LWNAF 4 +/** Chosen prime elliptic curve point multiplication method. */ +#define EP_FIX @EP_FIX@ + +/** Basic simultaneouns point multiplication. */ +#define BASIC 1 +/** Shamir's trick. */ +#define TRICK 2 +/** Interleaving of w-(T)NAFs. */ +#define INTER 3 +/** Joint sparse form. */ +#define JOINT 4 +/** Chosen prime elliptic curve simulteanous point multiplication method. */ +#define EP_SIM @EP_SIM@ + +/** Prime elliptic curve arithmetic method. */ +#define EP_METHD "@EP_METHD@" + +/** Support for ordinary curves without endormorphisms. */ +#cmakedefine EB_PLAIN +/** Support for Koblitz anomalous binary curves. */ +#cmakedefine EB_KBLTZ +/** Use mixed coordinates. */ +#cmakedefine EB_MIXED +/** Build precomputation table for generator. */ +#cmakedefine EB_PRECO +/** Width of precomputation table for fixed point methods. */ +#define EB_DEPTH @EB_DEPTH@ +/** Width of window processing for unknown point methods. */ +#define EB_WIDTH @EB_WIDTH@ + +/** Binary elliptic curve arithmetic method. */ +#define EB_METHD "@EB_METHD@" + +/** Affine coordinates. */ +#define BASIC 1 +/** López-Dahab Projective coordinates. */ +#define PROJC 2 +/** Chosen binary elliptic curve coordinate method. */ +#define EB_ADD @EB_ADD@ + +/** Binary point multiplication. */ +#define BASIC 1 +/** L�pez-Dahab point multiplication. */ +#define LODAH 2 +/** Halving. */ +#define HALVE 3 +/** Left-to-right width-w (T)NAF. */ +#define LWNAF 4 +/** Right-to-left width-w (T)NAF. */ +#define RWNAF 5 +/** Chosen binary elliptic curve point multiplication method. */ +#define EB_MUL @EB_MUL@ + +/** Binary point multiplication. */ +#define BASIC 1 +/** Single-table comb method. */ +#define COMBS 2 +/** Double-table comb method. */ +#define COMBD 3 +/** Left-to-right Width-w NAF. */ +#define LWNAF 4 +/** Chosen binary elliptic curve point multiplication method. */ +#define EB_FIX @EB_FIX@ + +/** Basic simultaneouns point multiplication. */ +#define BASIC 1 +/** Shamir's trick. */ +#define TRICK 2 +/** Interleaving of w-(T)NAFs. */ +#define INTER 3 +/** Joint sparse form. */ +#define JOINT 4 +/** Chosen binary elliptic curve simulteanous point multiplication method. */ +#define EB_SIM @EB_SIM@ + +/** Build precomputation table for generator. */ +#cmakedefine ED_PRECO +/** Width of precomputation table for fixed point methods. */ +#define ED_DEPTH @ED_DEPTH@ +/** Width of window processing for unknown point methods. */ +#define ED_WIDTH @ED_WIDTH@ + +/** Edwards elliptic curve arithmetic method. */ +#define ED_METHD "@ED_METHD@" + +/** Affine coordinates. */ +#define BASIC 1 +/** Simple projective twisted Edwards coordinates */ +#define PROJC 2 +/** Extended projective twisted Edwards coordinates */ +#define EXTND 3 +/** Chosen binary elliptic curve coordinate method. */ +#define ED_ADD @ED_ADD@ + +/** Binary point multiplication. */ +#define BASIC 1 +/** Sliding window. */ +#define SLIDE 2 +/** Montgomery powering ladder. */ +#define MONTY 3 +/** Left-to-right Width-w NAF. */ +#define LWNAF 4 +/** Left-to-right Width-w NAF. */ +#define LWREG 5 +/** Chosen prime elliptic twisted Edwards curve point multiplication method. */ +#define ED_MUL @ED_MUL@ + +/** Binary point multiplication. */ +#define BASIC 1 +/** Single-table comb method. */ +#define COMBS 2 +/** Double-table comb method. */ +#define COMBD 3 +/** Left-to-right Width-w NAF. */ +#define LWNAF 4 +/** Chosen prime elliptic twisted Edwards curve point multiplication method. */ +#define ED_FIX @ED_FIX@ + +/** Basic simultaneouns point multiplication. */ +#define BASIC 1 +/** Shamir's trick. */ +#define TRICK 2 +/** Interleaving of w-(T)NAFs. */ +#define INTER 3 +/** Joint sparse form. */ +#define JOINT 4 +/** Chosen prime elliptic curve simulteanous point multiplication method. */ +#define ED_SIM @ED_SIM@ + +/** Prime curves. */ +#define PRIME 1 +/** Binary curves. */ +#define CHAR2 2 +/** Edwards curves */ +#define EDDIE 3 +/** Chosen elliptic curve type. */ +#define EC_CUR @EC_CUR@ + +/** Chosen elliptic curve cryptography method. */ +#define EC_METHD "@EC_METHD@" +/** Prefer curves with efficient endomorphisms. */ +#cmakedefine EC_ENDOM + +/** Basic quadratic extension field arithmetic. */ +#define BASIC 1 +/** Lazy-reduced extension field arithmetic. */ +#define LAZYR 2 +/* Chosen extension field arithmetic method. */ +#define PP_EXT @PP_EXT@ + +/** Bilinear pairing method. */ +#define PP_METHD "@PP_METHD@" + +/** Tate pairing. */ +#define TATEP 1 +/** Weil pairing. */ +#define WEILP 2 +/** Optimal ate pairing. */ +#define OATEP 3 +/** Chosen pairing method over prime elliptic curves. */ +#define PP_MAP @PP_MAP@ + +/** SHA-224 hash function. */ +#define SH224 2 +/** SHA-256 hash function. */ +#define SH256 3 +/** SHA-384 hash function. */ +#define SH384 4 +/** SHA-512 hash function. */ +#define SH512 5 +/** BLAKE2s-160 hash function. */ +#define B2S160 6 +/** BLAKE2s-256 hash function. */ +#define B2S256 7 +/** Chosen hash function. */ +#define MD_MAP @MD_MAP@ + +/** Choice of hash function. */ +#define MD_METHD "@MD_METHD@" + +/** Chosen RSA method. */ +#cmakedefine CP_CRT +/** RSA without padding. */ +#define BASIC 1 +/** RSA PKCS#1 v1.5 padding. */ +#define PKCS1 2 +/** RSA PKCS#1 v2.1 padding. */ +#define PKCS2 3 +/** Chosen RSA padding method. */ +#define CP_RSAPD @CP_RSAPD@ + +/** Automatic memory allocation. */ +#define AUTO 1 +/** Dynamic memory allocation. */ +#define DYNAMIC 2 +/** Chosen memory allocation policy. */ +#define ALLOC @ALLOC@ + +/** NIST HASH-DRBG generator. */ +#define HASHD 1 +/** Intel RdRand instruction. */ +#define RDRND 2 +/** Operating system underlying generator. */ +#define UDEV 3 +/** Override library generator with the callback. */ +#define CALL 4 +/** Chosen random generator. */ +#define RAND @RAND@ + +/** Standard C library generator. */ +#define LIBC 1 +/** Intel RdRand instruction. */ +#define RDRND 2 +/** Device node generator. */ +#define UDEV 3 +/** Use Windows' CryptGenRandom. */ +#define WCGR 4 +/** Chosen random generator seeder. */ +#cmakedefine SEED @SEED@ + +/** GNU/Linux operating system. */ +#define LINUX 1 +/** FreeBSD operating system. */ +#define FREEBSD 2 +/** Windows operating system. */ +#define MACOSX 3 +/** Windows operating system. */ +#define WINDOWS 4 +/** Android operating system. */ +#define DROID 5 +/** Arduino platform. */ +#define DUINO 6 +/** OpenBSD operating system. */ +#define OPENBSD 7 +/** Detected operation system. */ +#cmakedefine OPSYS @OPSYS@ + +/** OpenMP multithreading support. */ +#define OPENMP 1 +/** POSIX multithreading support. */ +#define PTHREAD 2 +/** Chosen multithreading API. */ +#cmakedefine MULTI @MULTI@ + +/** Per-process high-resolution timer. */ +#define HREAL 1 +/** Per-process high-resolution timer. */ +#define HPROC 2 +/** Per-thread high-resolution timer. */ +#define HTHRD 3 +/** POSIX-compatible timer. */ +#define POSIX 4 +/** ANSI-compatible timer. */ +#define ANSI 5 +/** Cycle-counting timer. */ +#define CYCLE 6 +/** Performance monitoring framework. */ +#define PERF 7 +/** Chosen timer. */ +#cmakedefine TIMER @TIMER@ + +/** Prefix to identity this build of the library. */ +#cmakedefine LABEL @LABEL@ + +#ifndef ASM + +#include "relic_label.h" + +/** + * Prints the project options selected at build time. + */ +void conf_print(void); + +#endif /* ASM */ + +#endif /* !RLC_CONF_H */ From 730efde1090ceea4544a68b42e90fa915a80863a Mon Sep 17 00:00:00 2001 From: UdjinM6 Date: Wed, 28 Jun 2023 23:43:42 +0300 Subject: [PATCH 2/3] Squashed 'src/dashbls/' changes from 9329803969..795660db76 795660db76 chore: bump version to 1.3.0 (#84) e8743b0139 Merge pull request #83 from UdjinM6/bp_370_371 72f0ad2d37 fix: add missing destructor for CoreMPL and final for nested classes (#371) 2f05059c60 Fix a typo in class PrivateKey testcase. (#370) 851c2c8f68 fix: reading unitialized memory from Util::HasOnlyZeros in G2Element deserialization (#77) 4dd28e9016 fix: js bindings build (#82) 3697c51521 fix: dash is no more pretending being a 'libdashbls' (#76) 37c53141d3 feat: implement memory-copy only of G1Element and G2Element (#74) 97ac99e8e6 build(bls-dash-sys): ignore wasm32 target arch (#70) 2d494d351e Merge pull request #71 from dashpay/feat/threshold_bindings 67fb70d40b chore: revert permission changes in bcce0b214876c0d9e668baaa30a48542b496cda2 5a58fce0ea fix: resolve rust-bindings compilation failure 8604e03761 build: fix cmake build error c25957edf0 Merge remote-tracking branch 'dash/develop' into feat/threshold_bindings2 198e246f07 added a helper for verifying a message a4b8a5dd6e added a helper for verifying a message 2d783c985e added a helper for signing from the private key 16f7873d6a changed to using a slice for recovery a23d9708c0 feat: clone 0cf8a8eb96 feat: serde 47829e3e75 threshold_recovery functions a5589e6fc8 fix: bls extended private key size 1ceaab56e3 [add cpp targts] 86eb28e2d7 [fix linker path for cpp] 85debcab29 [include 'src' into build] f956c66b90 [switch into cc] 9ecb59bf9b [test linker] 3651a0fd79 [linker change] d8564679eb [fix: iossim] c829d4b6f1 [fix: aarch64-apple-darwin trigger] fc3509e901 [chore: silence warning] 79ce6ded50 [feat: apple build for single platform+arch] e580cb76db [feat: build for apple target] 17b2168955 feat: verifySecure method for BasicSchemeMPL in js bindings (#69) 4613425b60 chore: silence rust warnings 136d762607 [fix: target_arch] 0d8c8e9d41 [try to use ios.toolchain] bd441623df [back] 8137f48897 [change relic src] bdcba81d41 test: check patched relic 32b7f56d94 Merge pull request #1 from dashevo/rust-bindings-enhancement 6d359c6201 chore: test for extended private key from short seed 1cbeffe159 chore: add binding dace793a1a fix: same as previous: BIP32ExtendedPrivateKeyFromSeed with len 65c84d063c fix: ok now add second blank line 24b25bac2d fix: now try from typing import Union fe16287182 fix: try Union[Fq2, None] 3ffc96d409 fix: None 2d669a2cf8 chore: up version fbb5a43b19 fix: pass length PrivateKeyFromSeedBIP32 5822076d1a chore: cargo:fmt a8d3a7e956 test: add keys multiplication test 4b85f08937 fix: exchange keys when multiply 0bcefc68cb chore: add imports 7380332123 [chore: add binding for G1ElementMul] 881e6d7676 patch relic to be compatible with wasm bcce0b2148 chore: fix mode 02801cf973 add deeper checks to example project 6d25c60ee5 compilation fixes a4cebb4025 refactor: remove "C" prefix 995ef3796f refactor: bip32 feature 7ea0c34938 style: remove `get` prefix from getters e316c00f7b add VerifySecure da5536e1c5 feat: introduce PrivateKey::from_bip32_seed 4f03a1a1ae export legacy scheme 5c19e314d4 add extended private key cc081c0956 feat: add G1 element's fingerprint and generate methods f3e85b46d0 refactor: move back re-exports e8155b4bdb refactor: move legacy code to submodule f6e173242e add extendedpublickey 4f823249fb feat: legacy serialize and deserialize methods 90fd9f9c2c fix: comparison int with size_t 57237e5e87 Merge branch 'rust-bindings' of github.com:dashevo/bls-signatures into rust-bindings a1f862480b refactor: implement Deref trait for SecureBox 0b6f94e41f add LegacySchemeMPL aa19a77a40 refactor: small refactoring dae8b31042 make schemes public 827d1ed162 add hdkeys 7b4ffae5ec improve agg sig test 18057687be add basic scheme 3e4fdda2bd aggregates 61a4d791c9 elements ser/de 8b5b6301f3 wip 126b7becea wip c49514176e chore: remove autocxx variant 477c014bb7 refactor: increase `c_err_to_result` readability 5d52d0e59d Merge remote-tracking branch 'dashevo/rust-bindings' into rust-bindings 31724b39d1 chore: add example crate c04c2941db safe wrappers for simple case 844779cd81 chore: remove cdylib from bls-signatures d622625de4 chore: move all rust stuff into one 0d3c51106a Merge remote-tracking branch 'dashevo/rust-bindings' into rust-bindings ecf0271950 revert: bring back necessary c binding files :) 20e1cfe37b wip 654fc5e6a6 chore: remove unnecessary files from c binding 92ffd63c28 refactor: cargo build script 1d4d76fb05 chore: remove wrapper.h 20cc668708 qfix abb38804c7 Merge remote-tracking branch 'dashevo/rust-bindings' into rust-bindings 760a267ab7 build: fix mac related issues 8b083794a4 add destructors to bls-dash-sys basic test 6c54f0a01a Merge remote-tracking branch 'dashevo/rust-bindings' into rust-bindings fd526ab0db build: pass gmp lib path to build.rs a8aaccb510 rust-bindings sign and verify test simple 8447c1c112 wip bindings test 9390162e3c wip add rust-bindings tests 26ab7216c0 revert: bls header path db55e40cb0 rename to sys 96188a6d52 build qfix 965ac58df4 build: automate build process part 2 05636207a0 build: automate build process part 1 73b146a961 experiment cross compiling with autocxx and bindgen 969e5e2102 experiment cross compiling with autocxx and bindgen 88ee9d0519 chore: WIP 525b4d49d9 feat: rust bindings git-subtree-dir: src/dashbls git-subtree-split: 795660db76636c92bea3bfccfee621f1aba371a3 --- .gitignore | 3 + CMakeLists.txt | 29 +- apple.rust.deps.sh | 373 ++++++++++++++ apple.rust.sh | 458 ++++++++++++++++++ apple.rust.single.sh | 404 +++++++++++++++ configure.ac | 3 +- include/dashbls/elements.hpp | 2 + include/dashbls/schemes.hpp | 9 +- js-bindings/CMakeLists.txt | 2 +- js-bindings/blsjs.d.ts | 1 + js-bindings/jsbindings.cpp | 3 +- js-bindings/wrappers/SchemeMPLWrapper.h | 9 + python-impl/op_swu_g2.py | 3 +- rust-bindings/.gitignore | 2 + rust-bindings/bls-dash-sys/.rustfmt.toml | 17 + rust-bindings/bls-dash-sys/Cargo.toml | 15 + rust-bindings/bls-dash-sys/bindings.rs | 435 +++++++++++++++++ rust-bindings/bls-dash-sys/build.rs | 374 ++++++++++++++ .../c-bindings/bip32/chaincode.cpp | 25 + .../bls-dash-sys/c-bindings/bip32/chaincode.h | 21 + .../c-bindings/bip32/extendedprivatekey.cpp | 128 +++++ .../c-bindings/bip32/extendedprivatekey.h | 48 ++ .../c-bindings/bip32/extendedpublickey.cpp | 72 +++ .../c-bindings/bip32/extendedpublickey.h | 38 ++ .../bls-dash-sys/c-bindings/blschia.cpp | 56 +++ .../bls-dash-sys/c-bindings/blschia.h | 46 ++ .../bls-dash-sys/c-bindings/elements.cpp | 162 +++++++ .../bls-dash-sys/c-bindings/elements.h | 58 +++ rust-bindings/bls-dash-sys/c-bindings/error.h | 21 + .../bls-dash-sys/c-bindings/privatekey.cpp | 120 +++++ .../bls-dash-sys/c-bindings/privatekey.h | 40 ++ .../bls-dash-sys/c-bindings/schemes.cpp | 388 +++++++++++++++ .../bls-dash-sys/c-bindings/schemes.h | 184 +++++++ .../bls-dash-sys/c-bindings/threshold.cpp | 168 +++++++ .../bls-dash-sys/c-bindings/threshold.h | 55 +++ .../bls-dash-sys/c-bindings/utils.cpp | 40 ++ .../bls-dash-sys/c-bindings/utils.hpp | 34 ++ rust-bindings/bls-dash-sys/include.h | 8 + rust-bindings/bls-dash-sys/src/lib.rs | 6 + .../bls-dash-sys/tests/sign_and_verify.rs | 79 +++ rust-bindings/bls-signatures/.rustfmt.toml | 17 + rust-bindings/bls-signatures/Cargo.toml | 18 + .../bls-signatures/src/bip32/chain_code.rs | 33 ++ rust-bindings/bls-signatures/src/bip32/mod.rs | 7 + .../bls-signatures/src/bip32/private_key.rs | 205 ++++++++ .../bls-signatures/src/bip32/public_key.rs | 119 +++++ rust-bindings/bls-signatures/src/elements.rs | 368 ++++++++++++++ .../bls-signatures/src/legacy/bip32/mod.rs | 2 + .../src/legacy/bip32/private_key.rs | 58 +++ .../src/legacy/bip32/public_key.rs | 40 ++ .../bls-signatures/src/legacy/elements.rs | 25 + .../bls-signatures/src/legacy/mod.rs | 2 + rust-bindings/bls-signatures/src/lib.rs | 104 ++++ .../bls-signatures/src/private_key.rs | 315 ++++++++++++ rust-bindings/bls-signatures/src/schemes.rs | 434 +++++++++++++++++ rust-bindings/bls-signatures/src/utils.rs | 71 +++ rust-bindings/example/Cargo.toml | 7 + rust-bindings/example/src/main.rs | 51 ++ setjmp_patch.diff | 41 ++ src/CMakeLists.txt | 3 +- src/elements.cpp | 17 + src/test.cpp | 2 +- 62 files changed, 5866 insertions(+), 12 deletions(-) create mode 100755 apple.rust.deps.sh create mode 100755 apple.rust.sh create mode 100755 apple.rust.single.sh create mode 100644 rust-bindings/.gitignore create mode 100644 rust-bindings/bls-dash-sys/.rustfmt.toml create mode 100644 rust-bindings/bls-dash-sys/Cargo.toml create mode 100644 rust-bindings/bls-dash-sys/bindings.rs create mode 100644 rust-bindings/bls-dash-sys/build.rs create mode 100644 rust-bindings/bls-dash-sys/c-bindings/bip32/chaincode.cpp create mode 100644 rust-bindings/bls-dash-sys/c-bindings/bip32/chaincode.h create mode 100644 rust-bindings/bls-dash-sys/c-bindings/bip32/extendedprivatekey.cpp create mode 100644 rust-bindings/bls-dash-sys/c-bindings/bip32/extendedprivatekey.h create mode 100644 rust-bindings/bls-dash-sys/c-bindings/bip32/extendedpublickey.cpp create mode 100644 rust-bindings/bls-dash-sys/c-bindings/bip32/extendedpublickey.h create mode 100644 rust-bindings/bls-dash-sys/c-bindings/blschia.cpp create mode 100644 rust-bindings/bls-dash-sys/c-bindings/blschia.h create mode 100644 rust-bindings/bls-dash-sys/c-bindings/elements.cpp create mode 100644 rust-bindings/bls-dash-sys/c-bindings/elements.h create mode 100644 rust-bindings/bls-dash-sys/c-bindings/error.h create mode 100644 rust-bindings/bls-dash-sys/c-bindings/privatekey.cpp create mode 100644 rust-bindings/bls-dash-sys/c-bindings/privatekey.h create mode 100644 rust-bindings/bls-dash-sys/c-bindings/schemes.cpp create mode 100644 rust-bindings/bls-dash-sys/c-bindings/schemes.h create mode 100644 rust-bindings/bls-dash-sys/c-bindings/threshold.cpp create mode 100644 rust-bindings/bls-dash-sys/c-bindings/threshold.h create mode 100644 rust-bindings/bls-dash-sys/c-bindings/utils.cpp create mode 100644 rust-bindings/bls-dash-sys/c-bindings/utils.hpp create mode 100644 rust-bindings/bls-dash-sys/include.h create mode 100644 rust-bindings/bls-dash-sys/src/lib.rs create mode 100644 rust-bindings/bls-dash-sys/tests/sign_and_verify.rs create mode 100644 rust-bindings/bls-signatures/.rustfmt.toml create mode 100644 rust-bindings/bls-signatures/Cargo.toml create mode 100644 rust-bindings/bls-signatures/src/bip32/chain_code.rs create mode 100644 rust-bindings/bls-signatures/src/bip32/mod.rs create mode 100644 rust-bindings/bls-signatures/src/bip32/private_key.rs create mode 100644 rust-bindings/bls-signatures/src/bip32/public_key.rs create mode 100644 rust-bindings/bls-signatures/src/elements.rs create mode 100644 rust-bindings/bls-signatures/src/legacy/bip32/mod.rs create mode 100644 rust-bindings/bls-signatures/src/legacy/bip32/private_key.rs create mode 100644 rust-bindings/bls-signatures/src/legacy/bip32/public_key.rs create mode 100644 rust-bindings/bls-signatures/src/legacy/elements.rs create mode 100644 rust-bindings/bls-signatures/src/legacy/mod.rs create mode 100644 rust-bindings/bls-signatures/src/lib.rs create mode 100755 rust-bindings/bls-signatures/src/private_key.rs create mode 100644 rust-bindings/bls-signatures/src/schemes.rs create mode 100644 rust-bindings/bls-signatures/src/utils.rs create mode 100644 rust-bindings/example/Cargo.toml create mode 100644 rust-bindings/example/src/main.rs create mode 100644 setjmp_patch.diff diff --git a/.gitignore b/.gitignore index 38818e6ab8..bec3896a5c 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,7 @@ blspy.*.so .mypy_cache/ .pytest_chache/ .eggs/ +cmake-build-debug/ js_build node_modules @@ -67,6 +68,8 @@ yarn-error.log .vs/ out/ +target + Makefile.in /ar-lib /mdate-sh diff --git a/CMakeLists.txt b/CMakeLists.txt index f730426e1f..f413f97cc7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,6 +14,7 @@ endif() project(BLS) +set(BUILD_BLS_JS_BINDINGS "1" CACHE STRING "") set(BUILD_BLS_PYTHON_BINDINGS "1" CACHE STRING "") set(BUILD_BLS_TESTS "1" CACHE STRING "") set(BUILD_BLS_BENCHMARKS "1" CACHE STRING "") @@ -110,10 +111,36 @@ set(MI_OVERRIDE "off" CACHE STRING "") add_subdirectory(depends/relic) add_subdirectory(depends/mimalloc) +#message(STATUS "Patching Relic to make setjmp.h inclusion conditional") +# +#execute_process( +# COMMAND bash -c "git apply ${CMAKE_SOURCE_DIR}/setjmp_patch.diff" +# WORKING_DIRECTORY ${RELIC_SRC} +#) + add_subdirectory(src) + +# Write include paths for rust binding if(EMSCRIPTEN) - add_subdirectory(js-bindings) + file(APPEND "${CMAKE_CURRENT_LIST_DIR}/build/include_paths.txt" "${CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES}/c++/v1/;") +endif() + +file(APPEND "${CMAKE_CURRENT_LIST_DIR}/build/include_paths.txt" "${CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES};") + +if(GMP_INCLUDES) + file(APPEND "${CMAKE_CURRENT_LIST_DIR}/build/include_paths.txt" "${GMP_INCLUDES};") +endif() + +# Write gmp library path for rust binding +if(GMP_LIBRARIES) + file(APPEND "${CMAKE_CURRENT_LIST_DIR}/build/gmp_libraries.txt" "${GMP_LIBRARIES}") +endif() + +if(EMSCRIPTEN) + if(BUILD_BLS_JS_BINDINGS) + add_subdirectory(js-bindings) + endif() else() # emscripten can't build python bindings, it produces only javascript # add_subdirectory(contrib/pybind11) diff --git a/apple.rust.deps.sh b/apple.rust.deps.sh new file mode 100755 index 0000000000..7d3b8de22f --- /dev/null +++ b/apple.rust.deps.sh @@ -0,0 +1,373 @@ +#!/bin/sh +set -x +# "x86_64-apple-ios" +# "aarch64-apple-ios" +# "aarch64-apple-ios-sim" +# "x86_64-apple-darwin" +# "aarch64-apple-darwin" +# TODO: it's probably needs to be optimized in order to increase better build velocity +# TODO: so we need to combine multiple targets +TARGET=$1 +git submodule update --init +MIN_IOS="13.0" +MIN_WATCHOS="5.0" +MIN_TVOS=$MIN_IOS +MIN_MACOS="10.15" + +IPHONEOS=iphoneos +IPHONESIMULATOR=iphonesimulator +WATCHOS=watchos +WATCHSIMULATOR=watchsimulator +TVOS=appletvos +TVSIMULATOR=appletvsimulator +MACOS=macosx + +LOGICALCPU_MAX=$(sysctl -n hw.logicalcpu_max) +BUILD=build + +version_min_flag() { + PLATFORM=$1 + FLAG="" + # shellcheck disable=SC2039 + # shellcheck disable=SC2053 + if [[ $PLATFORM = $IPHONEOS ]]; then + FLAG="-miphoneos-version-min=${MIN_IOS}" + elif [[ $PLATFORM = $IPHONESIMULATOR ]]; then + FLAG="-mios-simulator-version-min=${MIN_IOS}" + elif [[ $PLATFORM = $WATCHOS ]]; then + FLAG="-mwatchos-version-min=${MIN_WATCHOS}" + elif [[ $PLATFORM = $WATCHSIMULATOR ]]; then + FLAG="-mwatchos-simulator-version-min=${MIN_WATCHOS}" + elif [[ $PLATFORM = $TVOS ]]; then + FLAG="-mtvos-version-min=${MIN_TVOS}" + elif [[ $PLATFORM = $TVSIMULATOR ]]; then + FLAG="-mtvos-simulator-version-min=${MIN_TVOS}" + elif [[ $PLATFORM = $MACOS ]]; then + FLAG="-mmacosx-version-min=${MIN_MACOS}" + fi + echo $FLAG +} + + +prepare() { + download_gmp() { + GMP_VERSION="6.2.1" + CURRENT_DIR=$(pwd) + echo "$CURRENT_DIR" + # shellcheck disable=SC2039,SC2164 + pushd ${BUILD} + mkdir -p "contrib" + if [ ! -s "contrib/gmp-${GMP_VERSION}.tar.bz2" ]; then + curl -L -o "contrib/gmp-${GMP_VERSION}.tar.bz2" https://gmplib.org/download/gmp/gmp-${GMP_VERSION}.tar.bz2 + fi + rm -rf "contrib/gmp" + # shellcheck disable=SC2039,SC2164 + pushd contrib + tar xfj "gmp-${GMP_VERSION}.tar.bz2" + mv gmp-${GMP_VERSION} gmp + rm gmp/compat.c && cp ../../contrib/gmp-patch-6.2.1/compat.c gmp/compat.c + rm gmp/longlong.h && cp ../../contrib/gmp-patch-6.2.1/longlong.h gmp/longlong.h + # shellcheck disable=SC2039,SC2164 + popd #contrib + # shellcheck disable=SC2039,SC2164 + popd #build + } + + download_cmake_toolchain() { + if [ ! -s "${BUILD}/ios.toolchain.cmake" ]; then + SHA256_HASH="d02857ff6bd64f1d7109ca59c3e4f3b2f89d0663c412146e6977c679801b3243" + curl -o "${BUILD}/ios.toolchain.cmake" https://raw.githubusercontent.com/leetal/ios-cmake/c55677a4445b138c9ef2650d3c21f22cc78c2357/ios.toolchain.cmake + DOWNLOADED_HASH=$(shasum -a 256 ${BUILD}/ios.toolchain.cmake | cut -f 1 -d " ") + if [ $SHA256_HASH != "$DOWNLOADED_HASH" ]; then + echo "Error: sha256 checksum of ios.toolchain.cmake mismatch" >&2 + exit 1 + fi + fi + } + + download_relic() { + CURRENT_DIR=$(pwd) + echo "$CURRENT_DIR" + mkdir -p "${CURRENT_DIR}/${BUILD}/contrib" + if [ ! -s "${CURRENT_DIR}/${BUILD}/contrib/relic" ]; then + # shellcheck disable=SC2039,SC2164 + pushd "${CURRENT_DIR}/${BUILD}/contrib" + git clone --depth 1 --branch "feat/ios-support" https://github.com/pankcuf/relic + # shellcheck disable=SC2039,SC2164 + pushd relic + git fetch --depth 1 origin 19fb6d79a77ade4ae8cd70d2b0ef7aab8720d1ae + git checkout 19fb6d79a77ade4ae8cd70d2b0ef7aab8720d1ae + # shellcheck disable=SC2039,SC2164 + popd #relic + # shellcheck disable=SC2039,SC2164 + popd #contrib + fi + } + rm -rf ${BUILD} + mkdir -p ${BUILD} + download_relic + download_gmp + download_cmake_toolchain +} + +build_gmp_arch() { + PLATFORM=$1 + ARCH=$2 + PFX=${PLATFORM}-${ARCH} + # why this works with this host only? + HOST=arm-apple-darwin + # shellcheck disable=SC2039,SC2164 + pushd ${BUILD} + SDK=$(xcrun --sdk "$PLATFORM" --show-sdk-path) + PLATFORM_PATH=$(xcrun --sdk "$PLATFORM" --show-sdk-platform-path) + CLANG=$(xcrun --sdk "$PLATFORM" --find clang) + DEVELOPER=$(xcode-select --print-path) + CURRENT_DIR=$(pwd) + export PATH="${PLATFORM_PATH}/Developer/usr/bin:${DEVELOPER}/usr/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/homebrew/bin" + mkdir gmplib-"${PLATFORM}"-"${ARCH}" + CFLAGS="-Wno-unused-value -fembed-bitcode -arch ${ARCH} --sysroot=${SDK} $(version_min_flag "$PLATFORM")" + CONFIGURESCRIPT="gmp_configure_script.sh" + # shellcheck disable=SC2039,SC2164 + pushd contrib + # shellcheck disable=SC2039,SC2164 + pushd gmp + make clean || true + make distclean || true + echo "HOST: $HOST" + echo "PREFIX: ${CURRENT_DIR}/gmplib-${PFX}" + + cat >"$CONFIGURESCRIPT" << EOF +#!/bin/sh +./configure \ +CC="$CLANG" CFLAGS="$CFLAGS" CPPFLAGS="$CFLAGS" LDFLAGS="$CFLAGS" \ +--host=${HOST} --prefix="${CURRENT_DIR}/gmplib-${PFX}" \ +--disable-shared --enable-static --disable-assembly -v +EOF + + chmod a+x "$CONFIGURESCRIPT" + sh "$CONFIGURESCRIPT" + rm "$CONFIGURESCRIPT" + + # shellcheck disable=SC2039 + mkdir -p "${CURRENT_DIR}/log" + # shellcheck disable=SC2039 + make -j "$LOGICALCPU_MAX" &> "${CURRENT_DIR}"/log/gmplib-"${PFX}"-build.log + # shellcheck disable=SC2039 + make install &> "${CURRENT_DIR}"/log/gmplib-"${PFX}"-install.log + # shellcheck disable=SC2039,SC2164 + popd # gmp + # shellcheck disable=SC2039,SC2164 + popd # contrib + # shellcheck disable=SC2039,SC2164 + popd # build +} + +build_relic_arch() { + PLATFORM=$1 + ARCH=$2 + PFX=${PLATFORM}-${ARCH} + + # shellcheck disable=SC2039,SC2164 + pushd ${BUILD} + + SDK=$(xcrun --sdk "$PLATFORM" --show-sdk-path) + + BUILDDIR=relic-"${PFX}" + TOOLCHAIN=$(pwd)/ios.toolchain.cmake + GMP_PFX=$(pwd)/gmplib-${PFX} + rm -rf "$BUILDDIR" + mkdir "$BUILDDIR" + # shellcheck disable=SC2039,SC2164 + pushd "$BUILDDIR" + + unset CC + # shellcheck disable=SC2155 + export CC=$(xcrun --sdk "${PLATFORM}" --find clang) + + WSIZE=0 + IOS_PLATFORM="" + OPTIMIZATIONFLAGS="" + DEPLOYMENT_TARGET="" + + # shellcheck disable=SC2039 + # shellcheck disable=SC2053 + if [[ $PLATFORM = $IPHONEOS ]]; then + if [[ $ARCH = "arm64" ]] || [[ $ARCH = "arm64e" ]]; then + IOS_PLATFORM=OS64 + DEPLOYMENT_TARGET=$MIN_IOS + WSIZE=64 + OPTIMIZATIONFLAGS=-fomit-frame-pointer + else + IOS_PLATFORM=OS + WSIZE=32 + fi + elif [[ $PLATFORM = $IPHONESIMULATOR ]]; then + if [[ $ARCH = "x86_64" ]]; then + IOS_PLATFORM=SIMULATOR64 + DEPLOYMENT_TARGET=$MIN_IOS + WSIZE=64 + OPTIMIZATIONFLAGS=-fomit-frame-pointer + elif [[ $ARCH = "arm64" ]]; then + IOS_PLATFORM=SIMULATORARM64 + DEPLOYMENT_TARGET=$MIN_IOS + WSIZE=64 + else + IOS_PLATFORM=SIMULATOR + WSIZE=32 + fi + elif [[ $PLATFORM = $WATCHOS ]]; then + IOS_PLATFORM=WATCHOS + DEPLOYMENT_TARGET=$MIN_WATCHOS + WSIZE=32 + elif [[ $PLATFORM = $WATCHSIMULATOR ]]; then + IOS_PLATFORM=SIMULATOR_WATCHOS + DEPLOYMENT_TARGET=$MIN_WATCHOS + WSIZE=32 + elif [[ $PLATFORM = $TVOS ]]; then + IOS_PLATFORM=TVOS + DEPLOYMENT_TARGET=$MIN_TVOS + WSIZE=64 + OPTIMIZATIONFLAGS=-fomit-frame-pointer + elif [[ $PLATFORM = $TVSIMULATOR ]]; then + IOS_PLATFORM=SIMULATOR_TVOS + #TODO + if [[ $ARCH = "arm64" ]] + then + IOS_PLATFORM=OS64 + fi + DEPLOYMENT_TARGET=$MIN_TVOS + WSIZE=64 + OPTIMIZATIONFLAGS=-fomit-frame-pointer + elif [[ $PLATFORM = $MACOS ]]; then + WSIZE=64 + IOS_PLATFORM=MAC + if [[ $ARCH = "arm64" ]] + then + IOS_PLATFORM=MAC_ARM64 + fi + DEPLOYMENT_TARGET=$MIN_MACOS + OPTIMIZATIONFLAGS=-fomit-frame-pointer + fi + + COMPILER_ARGS="$(version_min_flag "$PLATFORM") -Wno-unused-functions" + + EXTRA_ARGS="-DOPSYS=NONE -DPLATFORM=$IOS_PLATFORM -DDEPLOYMENT_TARGET=$DEPLOYMENT_TARGET -DCMAKE_TOOLCHAIN_FILE=$TOOLCHAIN" + + # shellcheck disable=SC2039 + if [[ $ARCH = "i386" ]]; then + EXTRA_ARGS+=" -DARCH=X86" + elif [[ $ARCH = "x86_64" ]]; then + EXTRA_ARGS+=" -DARCH=X64" + else + EXTRA_ARGS+=" -DARCH=ARM" + if [[ $ARCH = "armv7s" ]]; then + EXTRA_ARGS+=" -DIOS_ARCH=armv7s" + elif [[ $ARCH = "armv7k" ]]; then + EXTRA_ARGS+=" -DIOS_ARCH=armv7k" + elif [[ $ARCH = "arm64_32" ]]; then + EXTRA_ARGS+=" -DIOS_ARCH=arm64_32" + fi + fi + + CURRENT_DIR=$(pwd) + cmake -DCMAKE_PREFIX_PATH:PATH="${GMP_PFX}" -DTESTS=0 -DBENCH=0 -DBUILD_BLS_JS_BINDINGS=0 -DBUILD_BLS_PYTHON_BINDINGS=0 \ + -DBUILD_BLS_BENCHMARKS=0 -DBUILD_BLS_TESTS=0 -DCHECK=off -DARITH=gmp -DTIMER=HPROC -DFP_PRIME=381 -DMULTI=PTHREAD \ + -DFP_QNRES=on -DFP_METHD="INTEG;INTEG;INTEG;MONTY;EXGCD;SLIDE" -DFPX_METHD="INTEG;INTEG;LAZYR" -DPP_METHD="LAZYR;OATEP" \ + -DCOMP_FLAGS="-pipe -std=c99 -O3 -funroll-loops $OPTIMIZATIONFLAGS -isysroot $SDK -arch $ARCH -fembed-bitcode ${COMPILER_ARGS}" \ + -DWSIZE=$WSIZE -DVERBS=off -DSHLIB=off -DALLOC="AUTO" -DEP_PLAIN=off -DEP_SUPER=off -DPP_EXT="LAZYR" \ + -DWITH="DV;BN;MD;FP;EP;FPX;EPX;PP;PC;CP" -DBN_METHD="COMBA;COMBA;MONTY;SLIDE;STEIN;BASIC" ${EXTRA_ARGS} ../../ + + make -j "$LOGICALCPU_MAX" + # shellcheck disable=SC2039,SC2164 + popd # "$BUILDDIR" + # shellcheck disable=SC2039,SC2164 + popd # contrib/relic +} + +build_bls_arch() { + # shellcheck disable=SC2039 + BLS_FILES=( "bls" "chaincode" "elements" "extendedprivatekey" "extendedpublickey" "legacy" "privatekey" "schemes" "threshold" ) + # shellcheck disable=SC2039 + ALL_BLS_OBJ_FILES=$(printf "%s.o " "${BLS_FILES[@]}") + + PLATFORM=$1 + ARCH=$2 + PFX=${PLATFORM}-${ARCH} + SDK=$(xcrun --sdk "$PLATFORM" --show-sdk-path) + + BUILDDIR=${BUILD}/bls-"${PFX}" + rm -rf "$BUILDDIR" + mkdir "$BUILDDIR" + # shellcheck disable=SC2039,SC2164 + pushd "$BUILDDIR" + + EXTRA_ARGS="$(version_min_flag "$PLATFORM")" + + CURRENT_DIR=$(pwd) + + # shellcheck disable=SC2039 + for F in "${BLS_FILES[@]}" + do + clang -I"../contrib/relic/include" \ + -I"../../depends/relic/include" \ + -I"../../include/dashbls" \ + -I"../relic-${PFX}/_deps/relic-build/include" \ + -I"../../src/" \ + -I"../gmplib-${PFX}/include" \ + -x c++ -std=c++14 -stdlib=libc++ -fembed-bitcode -arch "${ARCH}" -isysroot "${SDK}" "${EXTRA_ARGS}" \ + -c "../../src/${F}.cpp" -o "${F}.o" + done + + # shellcheck disable=SC2086 + xcrun -sdk "$PLATFORM" ar -cvq libbls.a $ALL_BLS_OBJ_FILES + + # shellcheck disable=SC2039,SC2164 + popd # "$BUILDDIR" +} + +build_all_arch() { + PLATFORM=$1 + ARCH=$2 + build_gmp_arch "$PLATFORM" "$ARCH" + build_relic_arch "$PLATFORM" "$ARCH" + build_bls_arch "$PLATFORM" "$ARCH" +} + +build_target() { + BUILD_IN=$1 + echo "Build target: $BUILD_IN" + ARCH="" + PLATFORM="" + # shellcheck disable=SC2039 + if [[ $BUILD_IN = "x86_64-apple-ios" ]]; then + ARCH=x86_64 + PLATFORM=$IPHONESIMULATOR + elif [[ $BUILD_IN = "aarch64-apple-ios" ]]; then + ARCH=arm64 + PLATFORM=$IPHONEOS + elif [[ $BUILD_IN = "aarch64-apple-ios-sim" ]]; then + ARCH=arm64 + PLATFORM=$IPHONESIMULATOR + elif [[ $BUILD_IN = "x86_64-apple-darwin" ]]; then + ARCH=x86_64 + PLATFORM=$MACOS + elif [[ $BUILD_IN = "aarch64-apple-darwin" ]]; then + ARCH=arm64 + PLATFORM=$MACOS + fi + build_all_arch "$PLATFORM" "$ARCH" + PFX="${PLATFORM}"-"${ARCH}" + rm -rf "build/artefacts/${BUILD_IN}" + mkdir -p "build/artefacts/${BUILD_IN}" + cp "build/gmplib-${PFX}/lib/libgmp.a" "build/artefacts/${BUILD_IN}" + cp "build/relic-${PFX}/_deps/relic-build/lib/librelic_s.a" "build/artefacts/${BUILD_IN}" + cp "build/relic-${PFX}/_deps/sodium-build/libsodium.a" "build/artefacts/${BUILD_IN}" + cp "build/bls-${PFX}/libbls.a" "build/artefacts/${BUILD_IN}" +# cp -rf build/bls-"${PFX}"/*.o build/artefacts/"${BUILD_IN}"/include +# cp -rf src/*.hpp build/artefacts/"${BUILD_IN}"/include +# cp -rf build/gmplib-"${PFX}"/include/gmp.h build/artefacts/"${BUILD_IN}"/include +# cp -rf build/relic-"${PFX}"/_deps/relic-build/include/*.h build/artefacts/"${BUILD_IN}"/include +} + +prepare +build_target "$TARGET" diff --git a/apple.rust.sh b/apple.rust.sh new file mode 100755 index 0000000000..e105c3ce6c --- /dev/null +++ b/apple.rust.sh @@ -0,0 +1,458 @@ +#!/bin/sh +set -x + +git submodule update --init + +MIN_IOS="13.0" +MIN_WATCHOS="5.0" +MIN_TVOS=$MIN_IOS +MIN_MACOS="10.15" + +IPHONEOS=iphoneos +IPHONESIMULATOR=iphonesimulator +WATCHOS=watchos +WATCHSIMULATOR=watchsimulator +TVOS=appletvos +TVSIMULATOR=appletvsimulator +MACOS=macosx + +LOGICALCPU_MAX=$(sysctl -n hw.logicalcpu_max) +BUILD=build + +version_min_flag() { + PLATFORM=$1 + FLAG="" + # shellcheck disable=SC2039 + # shellcheck disable=SC2053 + if [[ $PLATFORM = $IPHONEOS ]]; then + FLAG="-miphoneos-version-min=${MIN_IOS}" + elif [[ $PLATFORM = $IPHONESIMULATOR ]]; then + FLAG="-mios-simulator-version-min=${MIN_IOS}" + elif [[ $PLATFORM = $WATCHOS ]]; then + FLAG="-mwatchos-version-min=${MIN_WATCHOS}" + elif [[ $PLATFORM = $WATCHSIMULATOR ]]; then + FLAG="-mwatchos-simulator-version-min=${MIN_WATCHOS}" + elif [[ $PLATFORM = $TVOS ]]; then + FLAG="-mtvos-version-min=${MIN_TVOS}" + elif [[ $PLATFORM = $TVSIMULATOR ]]; then + FLAG="-mtvos-simulator-version-min=${MIN_TVOS}" + elif [[ $PLATFORM = $MACOS ]]; then + FLAG="-mmacosx-version-min=${MIN_MACOS}" + fi + echo $FLAG +} + + +prepare() { + download_gmp() { + GMP_VERSION="6.2.1" + CURRENT_DIR=$(pwd) + echo "$CURRENT_DIR" + # shellcheck disable=SC2039,SC2164 + pushd ${BUILD} + mkdir -p "contrib" + if [ ! -s "contrib/gmp-${GMP_VERSION}.tar.bz2" ]; then + curl -L -o "contrib/gmp-${GMP_VERSION}.tar.bz2" https://gmplib.org/download/gmp/gmp-${GMP_VERSION}.tar.bz2 + fi + rm -rf "contrib/gmp" + # shellcheck disable=SC2039,SC2164 + pushd contrib + tar xfj "gmp-${GMP_VERSION}.tar.bz2" + mv gmp-${GMP_VERSION} gmp + rm gmp/compat.c && cp ../../contrib/gmp-patch-6.2.1/compat.c gmp/compat.c + rm gmp/longlong.h && cp ../../contrib/gmp-patch-6.2.1/longlong.h gmp/longlong.h + # shellcheck disable=SC2039,SC2164 + popd #contrib + # shellcheck disable=SC2039,SC2164 + popd #build + } + + download_cmake_toolchain() { + if [ ! -s "${BUILD}/ios.toolchain.cmake" ]; then + SHA256_HASH="d02857ff6bd64f1d7109ca59c3e4f3b2f89d0663c412146e6977c679801b3243" + curl -o "${BUILD}/ios.toolchain.cmake" https://raw.githubusercontent.com/leetal/ios-cmake/c55677a4445b138c9ef2650d3c21f22cc78c2357/ios.toolchain.cmake + DOWNLOADED_HASH=$(shasum -a 256 ${BUILD}/ios.toolchain.cmake | cut -f 1 -d " ") + if [ $SHA256_HASH != "$DOWNLOADED_HASH" ]; then + echo "Error: sha256 checksum of ios.toolchain.cmake mismatch" >&2 + exit 1 + fi + fi + } + + download_relic() { + CURRENT_DIR=$(pwd) + echo "$CURRENT_DIR" + mkdir -p "${CURRENT_DIR}/${BUILD}/contrib" + if [ ! -s "${CURRENT_DIR}/${BUILD}/contrib/relic" ]; then + # shellcheck disable=SC2039,SC2164 + pushd "${CURRENT_DIR}/${BUILD}/contrib" + git clone --depth 1 --branch "feat/ios-support" https://github.com/pankcuf/relic + # shellcheck disable=SC2039,SC2164 + pushd relic + git fetch --depth 1 origin 19fb6d79a77ade4ae8cd70d2b0ef7aab8720d1ae + git checkout 19fb6d79a77ade4ae8cd70d2b0ef7aab8720d1ae + # shellcheck disable=SC2039,SC2164 + popd #relic + # shellcheck disable=SC2039,SC2164 + popd #contrib + fi + } + rm -rf ${BUILD} + mkdir -p ${BUILD} + download_relic + download_gmp + download_cmake_toolchain + mkdir -p ${BUILD}/artefacts/include +} + +build_gmp_arch() { + PLATFORM=$1 + ARCH=$2 + PFX=${PLATFORM}-${ARCH} + # why this works with this host only? + HOST=arm-apple-darwin + # shellcheck disable=SC2039,SC2164 + pushd ${BUILD} + SDK=$(xcrun --sdk "$PLATFORM" --show-sdk-path) + PLATFORM_PATH=$(xcrun --sdk "$PLATFORM" --show-sdk-platform-path) + CLANG=$(xcrun --sdk "$PLATFORM" --find clang) + DEVELOPER=$(xcode-select --print-path) + CURRENT_DIR=$(pwd) + export PATH="${PLATFORM_PATH}/Developer/usr/bin:${DEVELOPER}/usr/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/homebrew/bin" + mkdir gmplib-"${PLATFORM}"-"${ARCH}" + CFLAGS="-Wno-unused-value -fembed-bitcode -arch ${ARCH} --sysroot=${SDK} $(version_min_flag "$PLATFORM")" + CONFIGURESCRIPT="gmp_configure_script.sh" + # shellcheck disable=SC2039,SC2164 + pushd contrib + # shellcheck disable=SC2039,SC2164 + pushd gmp + make clean || true + make distclean || true + echo "HOST: $HOST" + echo "PREFIX: ${CURRENT_DIR}/gmplib-${PFX}" + + cat >"$CONFIGURESCRIPT" << EOF +#!/bin/sh +./configure \ +CC="$CLANG" CFLAGS="$CFLAGS" CPPFLAGS="$CFLAGS" LDFLAGS="$CFLAGS" \ +--host=${HOST} --prefix="${CURRENT_DIR}/gmplib-${PFX}" \ +--disable-shared --enable-static --disable-assembly -v +EOF + + chmod a+x "$CONFIGURESCRIPT" + sh "$CONFIGURESCRIPT" + rm "$CONFIGURESCRIPT" + + # shellcheck disable=SC2039 + mkdir -p "${CURRENT_DIR}/log" + # shellcheck disable=SC2039 + make -j "$LOGICALCPU_MAX" &> "${CURRENT_DIR}"/log/gmplib-"${PFX}"-build.log + # shellcheck disable=SC2039 + make install &> "${CURRENT_DIR}"/log/gmplib-"${PFX}"-install.log + # shellcheck disable=SC2039,SC2164 + popd # gmp + # shellcheck disable=SC2039,SC2164 + popd # contrib + # shellcheck disable=SC2039,SC2164 + popd # build +} + +build_relic_arch() { + PLATFORM=$1 + ARCH=$2 + PFX=${PLATFORM}-${ARCH} + + # shellcheck disable=SC2039,SC2164 + pushd ${BUILD} + + SDK=$(xcrun --sdk "$PLATFORM" --show-sdk-path) + + BUILDDIR=relic-"${PFX}" + TOOLCHAIN=$(pwd)/ios.toolchain.cmake + GMP_PFX=$(pwd)/gmplib-${PFX} + rm -rf "$BUILDDIR" + mkdir "$BUILDDIR" + # shellcheck disable=SC2039,SC2164 + pushd "$BUILDDIR" + + unset CC + # shellcheck disable=SC2155 + export CC=$(xcrun --sdk "${PLATFORM}" --find clang) + + WSIZE=0 + IOS_PLATFORM="" + OPTIMIZATIONFLAGS="" + DEPLOYMENT_TARGET="" + + # shellcheck disable=SC2039 + # shellcheck disable=SC2053 + if [[ $PLATFORM = $IPHONEOS ]]; then + if [[ $ARCH = "arm64" ]] || [[ $ARCH = "arm64e" ]]; then + IOS_PLATFORM=OS64 + DEPLOYMENT_TARGET=$MIN_IOS + WSIZE=64 + OPTIMIZATIONFLAGS=-fomit-frame-pointer + else + IOS_PLATFORM=OS + WSIZE=32 + fi + elif [[ $PLATFORM = $IPHONESIMULATOR ]]; then + if [[ $ARCH = "x86_64" ]]; then + IOS_PLATFORM=SIMULATOR64 + DEPLOYMENT_TARGET=$MIN_IOS + WSIZE=64 + OPTIMIZATIONFLAGS=-fomit-frame-pointer + elif [[ $ARCH = "arm64" ]]; then + IOS_PLATFORM=SIMULATORARM64 + DEPLOYMENT_TARGET=$MIN_IOS + WSIZE=64 + else + IOS_PLATFORM=SIMULATOR + WSIZE=32 + fi + elif [[ $PLATFORM = $WATCHOS ]]; then + IOS_PLATFORM=WATCHOS + DEPLOYMENT_TARGET=$MIN_WATCHOS + WSIZE=32 + elif [[ $PLATFORM = $WATCHSIMULATOR ]]; then + IOS_PLATFORM=SIMULATOR_WATCHOS + DEPLOYMENT_TARGET=$MIN_WATCHOS + WSIZE=32 + elif [[ $PLATFORM = $TVOS ]]; then + IOS_PLATFORM=TVOS + DEPLOYMENT_TARGET=$MIN_TVOS + WSIZE=64 + OPTIMIZATIONFLAGS=-fomit-frame-pointer + elif [[ $PLATFORM = $TVSIMULATOR ]]; then + IOS_PLATFORM=SIMULATOR_TVOS + #TODO + if [[ $ARCH = "arm64" ]] + then + IOS_PLATFORM=OS64 + fi + DEPLOYMENT_TARGET=$MIN_TVOS + WSIZE=64 + OPTIMIZATIONFLAGS=-fomit-frame-pointer + elif [[ $PLATFORM = $MACOS ]]; then + WSIZE=64 + IOS_PLATFORM=MAC + if [[ $ARCH = "arm64" ]] + then + IOS_PLATFORM=MAC_ARM64 + fi + DEPLOYMENT_TARGET=$MIN_MACOS + OPTIMIZATIONFLAGS=-fomit-frame-pointer + fi + + COMPILER_ARGS="$(version_min_flag "$PLATFORM") -Wno-unused-functions" + + EXTRA_ARGS="-DOPSYS=NONE -DPLATFORM=$IOS_PLATFORM -DDEPLOYMENT_TARGET=$DEPLOYMENT_TARGET -DCMAKE_TOOLCHAIN_FILE=$TOOLCHAIN" + + # shellcheck disable=SC2039 + if [[ $ARCH = "i386" ]]; then + EXTRA_ARGS+=" -DARCH=X86" + elif [[ $ARCH = "x86_64" ]]; then + EXTRA_ARGS+=" -DARCH=X64" + else + EXTRA_ARGS+=" -DARCH=ARM" + if [[ $ARCH = "armv7s" ]]; then + EXTRA_ARGS+=" -DIOS_ARCH=armv7s" + elif [[ $ARCH = "armv7k" ]]; then + EXTRA_ARGS+=" -DIOS_ARCH=armv7k" + elif [[ $ARCH = "arm64_32" ]]; then + EXTRA_ARGS+=" -DIOS_ARCH=arm64_32" + fi + fi + + CURRENT_DIR=$(pwd) + cmake -DCMAKE_PREFIX_PATH:PATH="${GMP_PFX}" -DTESTS=0 -DBENCH=0 -DBUILD_BLS_JS_BINDINGS=0 -DBUILD_BLS_PYTHON_BINDINGS=0 \ + -DBUILD_BLS_BENCHMARKS=0 -DBUILD_BLS_TESTS=0 -DCHECK=off -DARITH=gmp -DTIMER=HPROC -DFP_PRIME=381 -DMULTI=PTHREAD \ + -DFP_QNRES=on -DFP_METHD="INTEG;INTEG;INTEG;MONTY;EXGCD;SLIDE" -DFPX_METHD="INTEG;INTEG;LAZYR" -DPP_METHD="LAZYR;OATEP" \ + -DCOMP_FLAGS="-pipe -std=c99 -O3 -funroll-loops $OPTIMIZATIONFLAGS -isysroot $SDK -arch $ARCH -fembed-bitcode ${COMPILER_ARGS}" \ + -DWSIZE=$WSIZE -DVERBS=off -DSHLIB=off -DALLOC="AUTO" -DEP_PLAIN=off -DEP_SUPER=off -DPP_EXT="LAZYR" \ + -DWITH="DV;BN;MD;FP;EP;FPX;EPX;PP;PC;CP" -DBN_METHD="COMBA;COMBA;MONTY;SLIDE;STEIN;BASIC" ${EXTRA_ARGS} ../../ + + make -j "$LOGICALCPU_MAX" + # shellcheck disable=SC2039,SC2164 + popd # "$BUILDDIR" + # shellcheck disable=SC2039,SC2164 + popd # contrib/relic +} + +build_bls_arch() { + # shellcheck disable=SC2039 + BLS_FILES=( "bls" "chaincode" "elements" "extendedprivatekey" "extendedpublickey" "legacy" "privatekey" "schemes" "threshold" ) + # shellcheck disable=SC2039 + ALL_BLS_OBJ_FILES=$(printf "%s.o " "${BLS_FILES[@]}") + + PLATFORM=$1 + ARCH=$2 + PFX=${PLATFORM}-${ARCH} + SDK=$(xcrun --sdk "$PLATFORM" --show-sdk-path) + + BUILDDIR=${BUILD}/bls-"${PFX}" + rm -rf "$BUILDDIR" + mkdir "$BUILDDIR" + # shellcheck disable=SC2039,SC2164 + pushd "$BUILDDIR" + + EXTRA_ARGS="$(version_min_flag "$PLATFORM")" + + CURRENT_DIR=$(pwd) + + # shellcheck disable=SC2039 + for F in "${BLS_FILES[@]}" + do + clang -I"../contrib/relic/include" \ + -I"../relic-${PFX}/_deps/relic-build/include" \ + -I"../../src/" \ + -I"../gmplib-${PFX}/include" \ + -x c++ -std=c++14 -stdlib=libc++ -fembed-bitcode -arch "${ARCH}" -isysroot "${SDK}" "${EXTRA_ARGS}" \ + -c "../../src/${F}.cpp" -o "${F}.o" + done + + # shellcheck disable=SC2086 + xcrun -sdk "$PLATFORM" ar -cvq libbls.a $ALL_BLS_OBJ_FILES + + # shellcheck disable=SC2039,SC2164 + popd # "$BUILDDIR" +} + +build_all_arch() { + PLATFORM=$1 + ARCH=$2 + build_gmp_arch "$PLATFORM" "$ARCH" + build_relic_arch "$PLATFORM" "$ARCH" + build_bls_arch "$PLATFORM" "$ARCH" +} + +build_all() { + BUILD_IN=$1 + TARGET_DIR=build/artefacts + # shellcheck disable=SC2039 + IFS='|' read -ra BUILD_PAIRS <<< "$BUILD_IN" + # shellcheck disable=SC2039 + for BUILD_PAIR in "${BUILD_PAIRS[@]}" + do + # shellcheck disable=SC2039 + IFS=';' read -ra PARSED_PAIR <<< "$BUILD_PAIR" + # shellcheck disable=SC2039 + PLATFORM=${PARSED_PAIR[0]} + # shellcheck disable=SC2039 + ARCH=${PARSED_PAIR[1]} + + GMP_LIPOARGS="" + RELIC_LIPOARGS="" + BLS_LIPOARGS="" + + # shellcheck disable=SC2039 + local NEED_LIPO=0 + # shellcheck disable=SC2039 + IFS='+' read -ra ARCHS <<< "$ARCH" + # shellcheck disable=SC2039 + for i in "${!ARCHS[@]}" + do + # shellcheck disable=SC2039 + local SINGLEARCH=${ARCHS[i]} + + # build for every platform+arch + build_all_arch "$PLATFORM" "$SINGLEARCH" + + PFX="${PLATFORM}"-"${SINGLEARCH}" + ARCH_TARGET_DIR=${TARGET_DIR}/${PFX} + rm -rf "${ARCH_TARGET_DIR}" + mkdir -p "${ARCH_TARGET_DIR}" + #mv "${BUILD}/gmplib-${PFX}/lib/libgmp.a" "${ARCH_TARGET_DIR}/libgmp.a" + #mv "${BUILD}/relic-${PFX}/_deps/relic-build/lib/librelic_s.a" "${ARCH_TARGET_DIR}/librelic.a" + #mv "${BUILD}/bls-${PFX}/libbls.a" "${ARCH_TARGET_DIR}/libbls.a" + + libtool -static -o "${ARCH_TARGET_DIR}/libbls.a" \ + "${BUILD}/gmplib-${PFX}/lib/libgmp.a" \ + "${BUILD}/relic-${PFX}/_deps/relic-build/lib/librelic_s.a" \ + "${BUILD}/bls-${PFX}/libbls.a" + + # shellcheck disable=SC2039 + GMP_LIPOARGS+="${ARCH_TARGET_DIR}/libgmp.a " + # shellcheck disable=SC2039 + RELIC_LIPOARGS+="${ARCH_TARGET_DIR}/librelic.a " + # shellcheck disable=SC2039 + BLS_LIPOARGS+="${ARCH_TARGET_DIR}/libbls.a " + + NEED_LIPO=i + done + + # Do lipo if we need https://developer.apple.com/forums/thread/666335?answerId=645963022#645963022 +# if [[ $NEED_LIPO -gt 0 ]] +# then +# FAT_TARGET_DIR=${TARGET_DIR}/${PLATFORM}-fat +# rm -rf "${FAT_TARGET_DIR}" +# mkdir -p "${FAT_TARGET_DIR}" +# # shellcheck disable=SC2086 +# xcrun lipo $GMP_LIPOARGS -create -output "${FAT_TARGET_DIR}/libgmp.a" +# # shellcheck disable=SC2086 +# xcrun lipo $RELIC_LIPOARGS -create -output "${FAT_TARGET_DIR}/librelic.a" +# # shellcheck disable=SC2086 +# xcrun lipo $BLS_LIPOARGS -create -output "${FAT_TARGET_DIR}/libbls.a" +# libtool -static -o "${FAT_TARGET_DIR}/libbls_combined.a" "${FAT_TARGET_DIR}/libgmp.a" "${FAT_TARGET_DIR}/librelic.a" "${FAT_TARGET_DIR}/libbls.a" +# rm "${FAT_TARGET_DIR}/libgmp.a" +# rm "${FAT_TARGET_DIR}/librelic.a" +# rm "${FAT_TARGET_DIR}/libbls.a" +# mv "${FAT_TARGET_DIR}/libbls_combined.a" "${FAT_TARGET_DIR}/libbls.a" +# # clean up +# # shellcheck disable=SC2039 +# for i in "${!ARCHS[@]}" +# do +# local SINGLEARCH=${ARCHS[i]} +# rm -rf "${TARGET_DIR}-${SINGLEARCH}" +# done +# fi + done +} + +#make_relic_headers_universal() { +# RELIC_TARGET_DIR=relic-iphoneos-arm64 +# perl -p -e 's/#define WSIZE.*/#ifdef __LP64__\n#define WSIZE 64\n#else\n#define WSIZE 32\n#endif/' \ +# "build/contrib/relic/${RELIC_TARGET_DIR}/include/relic_conf.h" \ +# > "build/contrib/relic/${RELIC_TARGET_DIR}/include/relic_conf.h.new" +# +# rm "build/contrib/relic/${RELIC_TARGET_DIR}/include/relic_conf.h" +# mv "build/contrib/relic/${RELIC_TARGET_DIR}/include/relic_conf.h.new" "build/contrib/relic/${RELIC_TARGET_DIR}/include/relic_conf.h" +#} + +#copy_headers() { +# mkdir build/artefacts/include +# # Copy all headers we will need +# cp -rf src/*.hpp build/artefacts/include +# cp -rf build/gmp/include/gmp.h build/artefacts/include +# cp -rf build/contrib/relic/include/*.h build/artefacts/include +# cp -rf build/contrib/relic/include/low/*.h build/artefacts/include +# cp -rf build/contrib/relic/relic-iphoneos-arm64/include/*.h build/artefacts/include +# rm -rf build/artefacts/include/test-utils.hpp +#} + +#function make_fat_binary() +#{ +# pushd artefacts +# +# XCFRAMEWORK_ARGS="" +# +# for dir in */; do +# if [ -d "$dir" ]; then +# if [[ "$dir" != "include/" ]]; then +# libtool -static -o "${dir}libbls_combined.a" "${dir}libgmp.a" "${dir}librelic.a" "${dir}libbls.a" +# +# XCFRAMEWORK_ARGS+="-library ${dir}libbls_combined.a -headers include " +# fi +# fi +# done +# +# #xcodebuild -create-xcframework $XCFRAMEWORK_ARGS -output "libbls.xcframework" +#} + +prepare +build_all "${MACOS};x86_64+arm64" +build_all "${IPHONEOS};arm64|${IPHONESIMULATOR};arm64+x86_64" + +#make_relic_headers_universal +#copy_headers +#make_fat_binary diff --git a/apple.rust.single.sh b/apple.rust.single.sh new file mode 100755 index 0000000000..d99722bf02 --- /dev/null +++ b/apple.rust.single.sh @@ -0,0 +1,404 @@ +#!/bin/sh +set -x +# "x86_64-apple-ios" +# "x86_64-apple-ios-sim" +# "aarch64-apple-ios" +# "aarch64-apple-ios-sim" +# "x86_64-apple-darwin" +# "aarch64-apple-darwin" +# TODO: it's probably needs to be optimized in order to increase better build velocity +# TODO: so we need to combine multiple targets +TARGET=$1 +git submodule update --init +MIN_IOS="13.0" +MIN_WATCHOS="5.0" +MIN_TVOS=$MIN_IOS +MIN_MACOS="10.15" + +IPHONEOS=iphoneos +IPHONESIMULATOR=iphonesimulator +WATCHOS=watchos +WATCHSIMULATOR=watchsimulator +TVOS=appletvos +TVSIMULATOR=appletvsimulator +MACOS=macosx + +LOGICALCPU_MAX=$(sysctl -n hw.logicalcpu_max) +BUILD=build + +version_min_flag() { + PLATFORM=$1 + FLAG="" + # shellcheck disable=SC2039 + # shellcheck disable=SC2053 + if [[ $PLATFORM = $IPHONEOS ]]; then + FLAG="-miphoneos-version-min=${MIN_IOS}" + elif [[ $PLATFORM = $IPHONESIMULATOR ]]; then + FLAG="-mios-simulator-version-min=${MIN_IOS}" + elif [[ $PLATFORM = $WATCHOS ]]; then + FLAG="-mwatchos-version-min=${MIN_WATCHOS}" + elif [[ $PLATFORM = $WATCHSIMULATOR ]]; then + FLAG="-mwatchos-simulator-version-min=${MIN_WATCHOS}" + elif [[ $PLATFORM = $TVOS ]]; then + FLAG="-mtvos-version-min=${MIN_TVOS}" + elif [[ $PLATFORM = $TVSIMULATOR ]]; then + FLAG="-mtvos-simulator-version-min=${MIN_TVOS}" + elif [[ $PLATFORM = $MACOS ]]; then + FLAG="-mmacosx-version-min=${MIN_MACOS}" + fi + echo $FLAG +} + + +prepare() { + download_gmp() { + GMP_VERSION="6.2.1" + CURRENT_DIR=$(pwd) + echo "$CURRENT_DIR" + # shellcheck disable=SC2039,SC2164 + pushd ${BUILD} + mkdir -p "contrib" + if [ ! -s "contrib/gmp-${GMP_VERSION}.tar.bz2" ]; then + curl -L -o "contrib/gmp-${GMP_VERSION}.tar.bz2" https://gmplib.org/download/gmp/gmp-${GMP_VERSION}.tar.bz2 + fi + rm -rf "contrib/gmp" + # shellcheck disable=SC2039,SC2164 + pushd contrib + tar xfj "gmp-${GMP_VERSION}.tar.bz2" + mv gmp-${GMP_VERSION} gmp + rm gmp/compat.c && cp ../../contrib/gmp-patch-6.2.1/compat.c gmp/compat.c + rm gmp/longlong.h && cp ../../contrib/gmp-patch-6.2.1/longlong.h gmp/longlong.h + # shellcheck disable=SC2039,SC2164 + popd #contrib + # shellcheck disable=SC2039,SC2164 + popd #build + } + + download_cmake_toolchain() { + if [ ! -s "${BUILD}/ios.toolchain.cmake" ]; then + SHA256_HASH="d02857ff6bd64f1d7109ca59c3e4f3b2f89d0663c412146e6977c679801b3243" + curl -o "${BUILD}/ios.toolchain.cmake" https://raw.githubusercontent.com/leetal/ios-cmake/c55677a4445b138c9ef2650d3c21f22cc78c2357/ios.toolchain.cmake + DOWNLOADED_HASH=$(shasum -a 256 ${BUILD}/ios.toolchain.cmake | cut -f 1 -d " ") + if [ $SHA256_HASH != "$DOWNLOADED_HASH" ]; then + echo "Error: sha256 checksum of ios.toolchain.cmake mismatch" >&2 + exit 1 + fi + fi + } + + download_relic() { + CURRENT_DIR=$(pwd) + echo "$CURRENT_DIR" + mkdir -p "${CURRENT_DIR}/${BUILD}/contrib" + if [ ! -s "${CURRENT_DIR}/${BUILD}/contrib/relic" ]; then + # shellcheck disable=SC2039,SC2164 + pushd "${CURRENT_DIR}/${BUILD}/contrib" + git clone --depth 1 --branch "feat/ios-support" https://github.com/pankcuf/relic + # shellcheck disable=SC2039,SC2164 + pushd relic + git fetch --depth 1 origin 19fb6d79a77ade4ae8cd70d2b0ef7aab8720d1ae + git checkout 19fb6d79a77ade4ae8cd70d2b0ef7aab8720d1ae + # shellcheck disable=SC2039,SC2164 + popd #relic + # shellcheck disable=SC2039,SC2164 + popd #contrib + fi + } + rm -rf ${BUILD} + mkdir -p ${BUILD} + download_relic + download_gmp + download_cmake_toolchain +} + +build_gmp_arch() { + PLATFORM=$1 + ARCH=$2 + PFX=${PLATFORM}-${ARCH} + # why this works with this host only? + HOST=arm-apple-darwin + # shellcheck disable=SC2039,SC2164 + pushd ${BUILD} + SDK=$(xcrun --sdk "$PLATFORM" --show-sdk-path) + PLATFORM_PATH=$(xcrun --sdk "$PLATFORM" --show-sdk-platform-path) + CLANG=$(xcrun --sdk "$PLATFORM" --find clang) + DEVELOPER=$(xcode-select --print-path) + CURRENT_DIR=$(pwd) + export PATH="${PLATFORM_PATH}/Developer/usr/bin:${DEVELOPER}/usr/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/homebrew/bin" + mkdir gmplib-"${PLATFORM}"-"${ARCH}" + CFLAGS="-Wno-unused-value -fembed-bitcode -arch ${ARCH} --sysroot=${SDK} $(version_min_flag "$PLATFORM")" + CONFIGURESCRIPT="gmp_configure_script.sh" + # shellcheck disable=SC2039,SC2164 + pushd contrib + # shellcheck disable=SC2039,SC2164 + pushd gmp + make clean || true + make distclean || true + echo "HOST: $HOST" + echo "PREFIX: ${CURRENT_DIR}/gmplib-${PFX}" + + cat >"$CONFIGURESCRIPT" << EOF +#!/bin/sh +./configure \ +CC="$CLANG" CFLAGS="$CFLAGS" CPPFLAGS="$CFLAGS" LDFLAGS="$CFLAGS" \ +--host=${HOST} --prefix="${CURRENT_DIR}/gmplib-${PFX}" \ +--disable-shared --enable-static --disable-assembly -v +EOF + + chmod a+x "$CONFIGURESCRIPT" + sh "$CONFIGURESCRIPT" + rm "$CONFIGURESCRIPT" + + # shellcheck disable=SC2039 + mkdir -p "${CURRENT_DIR}/log" + # shellcheck disable=SC2039 + make -j "$LOGICALCPU_MAX" &> "${CURRENT_DIR}"/log/gmplib-"${PFX}"-build.log + # shellcheck disable=SC2039 + make install &> "${CURRENT_DIR}"/log/gmplib-"${PFX}"-install.log + # shellcheck disable=SC2039,SC2164 + popd # gmp + # shellcheck disable=SC2039,SC2164 + popd # contrib + # shellcheck disable=SC2039,SC2164 + popd # build +} + +build_relic_arch() { + PLATFORM=$1 + ARCH=$2 + PFX=${PLATFORM}-${ARCH} + + # shellcheck disable=SC2039,SC2164 + pushd ${BUILD} + + SDK=$(xcrun --sdk "$PLATFORM" --show-sdk-path) + + BUILDDIR=relic-"${PFX}" + TOOLCHAIN=$(pwd)/ios.toolchain.cmake + GMP_PFX=$(pwd)/gmplib-${PFX} + rm -rf "$BUILDDIR" + mkdir "$BUILDDIR" + # shellcheck disable=SC2039,SC2164 + pushd "$BUILDDIR" + + unset CC + # shellcheck disable=SC2155 + export CC=$(xcrun --sdk "${PLATFORM}" --find clang) + + WSIZE=0 + IOS_PLATFORM="" + OPTIMIZATIONFLAGS="" + DEPLOYMENT_TARGET="" + + # shellcheck disable=SC2039 + # shellcheck disable=SC2053 + if [[ $PLATFORM = $IPHONEOS ]]; then + if [[ $ARCH = "arm64" ]] || [[ $ARCH = "arm64e" ]]; then + IOS_PLATFORM=OS64 + DEPLOYMENT_TARGET=$MIN_IOS + WSIZE=64 + OPTIMIZATIONFLAGS=-fomit-frame-pointer + else + IOS_PLATFORM=OS + WSIZE=32 + fi + elif [[ $PLATFORM = $IPHONESIMULATOR ]]; then + if [[ $ARCH = "x86_64" ]]; then + IOS_PLATFORM=SIMULATOR64 + DEPLOYMENT_TARGET=$MIN_IOS + WSIZE=64 + OPTIMIZATIONFLAGS=-fomit-frame-pointer + elif [[ $ARCH = "arm64" ]]; then + IOS_PLATFORM=SIMULATORARM64 + DEPLOYMENT_TARGET=$MIN_IOS + WSIZE=64 + else + IOS_PLATFORM=SIMULATOR + WSIZE=32 + fi + elif [[ $PLATFORM = $WATCHOS ]]; then + IOS_PLATFORM=WATCHOS + DEPLOYMENT_TARGET=$MIN_WATCHOS + WSIZE=32 + elif [[ $PLATFORM = $WATCHSIMULATOR ]]; then + IOS_PLATFORM=SIMULATOR_WATCHOS + DEPLOYMENT_TARGET=$MIN_WATCHOS + WSIZE=32 + elif [[ $PLATFORM = $TVOS ]]; then + IOS_PLATFORM=TVOS + DEPLOYMENT_TARGET=$MIN_TVOS + WSIZE=64 + OPTIMIZATIONFLAGS=-fomit-frame-pointer + elif [[ $PLATFORM = $TVSIMULATOR ]]; then + IOS_PLATFORM=SIMULATOR_TVOS + #TODO + if [[ $ARCH = "arm64" ]] + then + IOS_PLATFORM=OS64 + fi + DEPLOYMENT_TARGET=$MIN_TVOS + WSIZE=64 + OPTIMIZATIONFLAGS=-fomit-frame-pointer + elif [[ $PLATFORM = $MACOS ]]; then + WSIZE=64 + IOS_PLATFORM=MAC + if [[ $ARCH = "arm64" ]] + then + IOS_PLATFORM=MAC_ARM64 + fi + DEPLOYMENT_TARGET=$MIN_MACOS + OPTIMIZATIONFLAGS=-fomit-frame-pointer + fi + + COMPILER_ARGS="$(version_min_flag "$PLATFORM") -Wno-unused-functions" + + EXTRA_ARGS="-DOPSYS=NONE -DPLATFORM=$IOS_PLATFORM -DDEPLOYMENT_TARGET=$DEPLOYMENT_TARGET -DCMAKE_TOOLCHAIN_FILE=$TOOLCHAIN" + + # shellcheck disable=SC2039 + if [[ $ARCH = "i386" ]]; then + EXTRA_ARGS+=" -DARCH=X86" + elif [[ $ARCH = "x86_64" ]]; then + EXTRA_ARGS+=" -DARCH=X64" + else + EXTRA_ARGS+=" -DARCH=ARM" + if [[ $ARCH = "armv7s" ]]; then + EXTRA_ARGS+=" -DIOS_ARCH=armv7s" + elif [[ $ARCH = "armv7k" ]]; then + EXTRA_ARGS+=" -DIOS_ARCH=armv7k" + elif [[ $ARCH = "arm64_32" ]]; then + EXTRA_ARGS+=" -DIOS_ARCH=arm64_32" + fi + fi + + CURRENT_DIR=$(pwd) + cmake -DCMAKE_PREFIX_PATH:PATH="${GMP_PFX}" -DTESTS=0 -DBENCH=0 -DBUILD_BLS_JS_BINDINGS=0 -DBUILD_BLS_PYTHON_BINDINGS=0 \ + -DBUILD_BLS_BENCHMARKS=0 -DBUILD_BLS_TESTS=0 -DCHECK=off -DARITH=gmp -DTIMER=HPROC -DFP_PRIME=381 -DMULTI=PTHREAD \ + -DFP_QNRES=on -DFP_METHD="INTEG;INTEG;INTEG;MONTY;EXGCD;SLIDE" -DFPX_METHD="INTEG;INTEG;LAZYR" -DPP_METHD="LAZYR;OATEP" \ + -DCOMP_FLAGS="-pipe -std=c99 -O3 -funroll-loops $OPTIMIZATIONFLAGS -isysroot $SDK -arch $ARCH -fembed-bitcode ${COMPILER_ARGS}" \ + -DWSIZE=$WSIZE -DVERBS=off -DSHLIB=off -DALLOC="AUTO" -DEP_PLAIN=off -DEP_SUPER=off -DPP_EXT="LAZYR" \ + -DWITH="DV;BN;MD;FP;EP;FPX;EPX;PP;PC;CP" -DBN_METHD="COMBA;COMBA;MONTY;SLIDE;STEIN;BASIC" ${EXTRA_ARGS} ../../ + + make -j "$LOGICALCPU_MAX" + # shellcheck disable=SC2039,SC2164 + popd # "$BUILDDIR" + # shellcheck disable=SC2039,SC2164 + popd # contrib/relic +} + +build_bls_arch() { + # shellcheck disable=SC2039 + BLS_FILES=( "bls" "chaincode" "elements" "extendedprivatekey" "extendedpublickey" "legacy" "privatekey" "schemes" "threshold" ) + # shellcheck disable=SC2039 + ALL_BLS_OBJ_FILES=$(printf "%s.o " "${BLS_FILES[@]}") + + PLATFORM=$1 + ARCH=$2 + PFX=${PLATFORM}-${ARCH} + SDK=$(xcrun --sdk "$PLATFORM" --show-sdk-path) + + BUILDDIR=${BUILD}/bls-"${PFX}" + rm -rf "$BUILDDIR" + mkdir "$BUILDDIR" + # shellcheck disable=SC2039,SC2164 + pushd "$BUILDDIR" + + EXTRA_ARGS="$(version_min_flag "$PLATFORM")" + + CURRENT_DIR=$(pwd) + + # shellcheck disable=SC2039 + for F in "${BLS_FILES[@]}" + do + clang -I"../contrib/relic/include" \ + -I"../relic-${PFX}/_deps/relic-build/include" \ + -I"../../src/" \ + -I"../gmplib-${PFX}/include" \ + -x c++ -std=c++14 -stdlib=libc++ -fembed-bitcode -arch "${ARCH}" -isysroot "${SDK}" "${EXTRA_ARGS}" \ + -c "../../src/${F}.cpp" -o "${F}.o" + done + + # shellcheck disable=SC2086 + xcrun -sdk "$PLATFORM" ar -cvq libbls.a $ALL_BLS_OBJ_FILES + + # shellcheck disable=SC2039,SC2164 + popd # "$BUILDDIR" +} + +build_all_arch() { + PLATFORM=$1 + ARCH=$2 + build_gmp_arch "$PLATFORM" "$ARCH" + build_relic_arch "$PLATFORM" "$ARCH" + build_bls_arch "$PLATFORM" "$ARCH" +} + +build_target() { + BUILD_IN=$1 + echo "Build target: $BUILD_IN" + ARCH="" + PLATFORM="" + # shellcheck disable=SC2039 + if [[ $BUILD_IN = "x86_64-apple-ios" ]]; then + ARCH=x86_64 + PLATFORM=$IPHONESIMULATOR + elif [[ $BUILD_IN = "aarch64-apple-ios" ]]; then + ARCH=arm64 + PLATFORM=$IPHONEOS + elif [[ $BUILD_IN = "aarch64-apple-ios-sim" ]]; then + ARCH=arm64 + PLATFORM=$IPHONESIMULATOR + elif [[ $BUILD_IN = "x86_64-apple-darwin" ]]; then + ARCH=x86_64 + PLATFORM=$MACOS + elif [[ $BUILD_IN = "aarch64-apple-darwin" ]]; then + ARCH=arm64 + PLATFORM=$MACOS + fi + build_all_arch "$PLATFORM" "$ARCH" + PFX="${PLATFORM}"-"${ARCH}" + rm -rf "build/artefacts/${BUILD_IN}" + mkdir -p "build/artefacts/${BUILD_IN}/include" +# libtool -static -o "build/artefacts/${BUILD_IN}/libbls.a" \ +# "build/gmplib-${PFX}/lib/libgmp.a" \ +# "build/relic-${PFX}/_deps/relic-build/lib/librelic_s.a" \ +# "build/bls-${PFX}/libbls.a" + cp "build/gmplib-${PFX}/lib/libgmp.a" "build/artefacts/${BUILD_IN}" + cp "build/relic-${PFX}/_deps/relic-build/lib/librelic_s.a" "build/artefacts/${BUILD_IN}" + cp "build/relic-${PFX}/_deps/sodium-build/libsodium.a" "build/artefacts/${BUILD_IN}" + cp "build/bls-${PFX}/libbls.a" "build/artefacts/${BUILD_IN}" + cp -rf build/bls-"${PFX}"/*.o build/artefacts/"${BUILD_IN}"/include + cp -rf src/*.hpp build/artefacts/"${BUILD_IN}"/include + cp -rf build/gmplib-"${PFX}"/include/gmp.h build/artefacts/"${BUILD_IN}"/include + cp -rf build/relic-"${PFX}"/_deps/relic-build/include/*.h build/artefacts/"${BUILD_IN}"/include +} + +#make_relic_headers_universal() { +# RELIC_TARGET_DIR=relic-iphoneos-arm64 +# perl -p -e 's/#define WSIZE.*/#ifdef __LP64__\n#define WSIZE 64\n#else\n#define WSIZE 32\n#endif/' \ +# "build/contrib/relic/${RELIC_TARGET_DIR}/include/relic_conf.h" \ +# > "build/contrib/relic/${RELIC_TARGET_DIR}/include/relic_conf.h.new" +# +# rm "build/contrib/relic/${RELIC_TARGET_DIR}/include/relic_conf.h" +# mv "build/contrib/relic/${RELIC_TARGET_DIR}/include/relic_conf.h.new" "build/contrib/relic/${RELIC_TARGET_DIR}/include/relic_conf.h" +#} +# +#copy_headers() { +## mkdir build/artefacts/include +# # Copy all headers we will need +# cp -rf src/*.hpp ${BUILD}/artefacts/include +# cp -rf ${BUILD}/contrib/gmp/include/gmp.h ${BUILD}/artefacts/include +# cp -rf ${BUILD}/contrib/relic/include/*.h ${BUILD}/artefacts/include +# cp -rf ${BUILD}/contrib/relic/include/low/*.h ${BUILD}/artefacts/include +# #cp -rf ${BUILD}/contrib/relic/relic-iphoneos-arm64/include/*.h ${BUILD}/artefacts/include +# rm -rf ${BUILD}/artefacts/include/test-utils.hpp +#} + +prepare +build_target "$TARGET" +#copy_headers +#build_all "${MACOS};x86_64+arm64" +#build_all "${IPHONEOS};arm64|${IPHONESIMULATOR};arm64+x86_64" + +#make_relic_headers_universal +#copy_headers +#make_fat_binary diff --git a/configure.ac b/configure.ac index 32900bb14f..23b61ec455 100644 --- a/configure.ac +++ b/configure.ac @@ -1,5 +1,5 @@ AC_PREREQ([2.60]) -AC_INIT([libdashbls],[1.2.4]) +AC_INIT([libdashbls],[1.3.0]) AC_CONFIG_AUX_DIR([build-aux]) AC_CONFIG_MACRO_DIR([build-aux/m4]) @@ -783,3 +783,4 @@ AC_OUTPUT dnl Peplace conflict-prone PACKAGE-prefixed macros with DASHBLS sed -i.old 's/PACKAGE/DASHBLS/g' depends/relic/include/relic_conf.h +sed -i.old 's/PACKAGE/DASHBLS/g' config.status diff --git a/include/dashbls/elements.hpp b/include/dashbls/elements.hpp index a147115907..6832b31f3a 100644 --- a/include/dashbls/elements.hpp +++ b/include/dashbls/elements.hpp @@ -59,6 +59,7 @@ public: GTElement Pair(const G2Element &b) const; uint32_t GetFingerprint(bool fLegacy = false) const; std::vector Serialize(bool fLegacy = false) const; + G1Element Copy(); friend bool operator==(const G1Element &a, const G1Element &b); friend bool operator!=(const G1Element &a, const G1Element &b); @@ -101,6 +102,7 @@ public: G2Element Negate() const; GTElement Pair(const G1Element &a) const; std::vector Serialize(bool fLegacy = false) const; + G2Element Copy(); friend bool operator==(G2Element const &a, G2Element const &b); friend bool operator!=(G2Element const &a, G2Element const &b); diff --git a/include/dashbls/schemes.hpp b/include/dashbls/schemes.hpp index 456ae749af..31e6b1a1b7 100644 --- a/include/dashbls/schemes.hpp +++ b/include/dashbls/schemes.hpp @@ -39,6 +39,7 @@ class CoreMPL { public: CoreMPL() = delete; CoreMPL(const std::string& strId) : strCiphersuiteId(strId) {} + virtual ~CoreMPL() {} // Generates a private key from a seed, similar to HD key generation // (hashes the seed), and reduces it mod the group order virtual PrivateKey KeyGen(const vector& seed); @@ -112,7 +113,7 @@ protected: bool fLegacy); }; -class BasicSchemeMPL : public CoreMPL { +class BasicSchemeMPL final : public CoreMPL { public: static const std::string CIPHERSUITE_ID; BasicSchemeMPL() : CoreMPL(BasicSchemeMPL::CIPHERSUITE_ID) {} @@ -133,7 +134,7 @@ public: const G2Element& signature) override; }; -class AugSchemeMPL : public CoreMPL { +class AugSchemeMPL final : public CoreMPL { public: static const std::string CIPHERSUITE_ID; @@ -186,7 +187,7 @@ public: const G2Element& signature) override; }; -class PopSchemeMPL : public CoreMPL { +class PopSchemeMPL final : public CoreMPL { public: static const std::string CIPHERSUITE_ID; @@ -221,7 +222,7 @@ public: /** * This scheme reflects the Sign/Verify behaviour of older bls-signatures library versions (<0.1.29). */ -class LegacySchemeMPL : public CoreMPL { +class LegacySchemeMPL final : public CoreMPL { public: LegacySchemeMPL() : CoreMPL(std::string{}) {} diff --git a/js-bindings/CMakeLists.txt b/js-bindings/CMakeLists.txt index 55de66444a..03da706af7 100644 --- a/js-bindings/CMakeLists.txt +++ b/js-bindings/CMakeLists.txt @@ -34,5 +34,5 @@ foreach(file ${JS_BINDINGS_TESTS}) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/tests/${file} tests/${file} COPYONLY) endforeach() -set_target_properties(blsjstmp PROPERTIES LINK_FLAGS "--bind -Oz --closure 1 -s MODULARIZE=1 -s NODEJS_CATCH_EXIT=1 -s NODEJS_CATCH_REJECTION=1") +set_target_properties(blsjstmp PROPERTIES LINK_FLAGS "--bind -Oz --closure 1 -s MODULARIZE=1") add_custom_command(TARGET blsjstmp POST_BUILD COMMAND npm run build:web) diff --git a/js-bindings/blsjs.d.ts b/js-bindings/blsjs.d.ts index 4cd30bc621..95cb05962a 100644 --- a/js-bindings/blsjs.d.ts +++ b/js-bindings/blsjs.d.ts @@ -21,6 +21,7 @@ export declare class BasicSchemeMPL { static deriveChildSk(sk: PrivateKey, index: number): PrivateKey; static deriveChildSkUnhardened(sk: PrivateKey, index: number): PrivateKey; static deriveChildPkUnhardened(pk: G1Element, index: number): G1Element; + static verifySecure(pk: G1Element, sig: G2Element, msg: Uint8Array): boolean; } export declare class PopSchemeMPL { diff --git a/js-bindings/jsbindings.cpp b/js-bindings/jsbindings.cpp index f390923eb8..81daa4abc7 100644 --- a/js-bindings/jsbindings.cpp +++ b/js-bindings/jsbindings.cpp @@ -42,7 +42,8 @@ EMSCRIPTEN_BINDINGS(blsjs) { .class_function("aggregateVerify", &SchemeMPLWrapper::AggregateVerify) .class_function("deriveChildSk", &SchemeMPLWrapper::DeriveChildSk) .class_function("deriveChildSkUnhardened", &SchemeMPLWrapper::DeriveChildSkUnhardened) - .class_function("deriveChildPkUnhardened", &SchemeMPLWrapper::DeriveChildPkUnhardened); + .class_function("deriveChildPkUnhardened", &SchemeMPLWrapper::DeriveChildPkUnhardened) + .class_function("verifySecure", &SchemeMPLWrapper::VerifySecure); class_("PopSchemeMPL") .class_function("skToG1", &PopSchemeMPLWrapper::SkToG1) diff --git a/js-bindings/wrappers/SchemeMPLWrapper.h b/js-bindings/wrappers/SchemeMPLWrapper.h index 972d7e3a76..e5a4ae5ef8 100644 --- a/js-bindings/wrappers/SchemeMPLWrapper.h +++ b/js-bindings/wrappers/SchemeMPLWrapper.h @@ -81,6 +81,15 @@ template class SchemeMPLWrapper : public JSWrapper pubkeys = G1ElementWrapper::Unwrap + (helpers::toVectorFromJSArray(pubkeyArray)); + + std::vector message = helpers::toVector(messageVal); + + return mpl.VerifySecure(pubkeys, signature.GetWrappedInstance(), message); + } + protected: static inline SchemeMPL mpl; }; diff --git a/python-impl/op_swu_g2.py b/python-impl/op_swu_g2.py index 2872611215..afdb40cf71 100644 --- a/python-impl/op_swu_g2.py +++ b/python-impl/op_swu_g2.py @@ -21,6 +21,7 @@ from bls12381 import h_eff, q from ec import JacobianPoint, default_ec_twist, eval_iso from fields import Fq, Fq2, roots_of_unity from hash_to_field import Hp2 +from typing import Union def sgn0(x: Fq2) -> int: @@ -198,7 +199,7 @@ def iso3(P): # # map from Fq2 element(s) to point in G2 subgroup of Ell2 # -def opt_swu2_map(t: Fq2, t2: Fq2 = None) -> JacobianPoint: +def opt_swu2_map(t: Fq2, t2: Union[Fq2, None] = None) -> JacobianPoint: Pp = iso3(osswu2_help(t)) if t2 is not None: Pp2 = iso3(osswu2_help(t2)) diff --git a/rust-bindings/.gitignore b/rust-bindings/.gitignore new file mode 100644 index 0000000000..cb117fd6ee --- /dev/null +++ b/rust-bindings/.gitignore @@ -0,0 +1,2 @@ +Cargo.lock +target \ No newline at end of file diff --git a/rust-bindings/bls-dash-sys/.rustfmt.toml b/rust-bindings/bls-dash-sys/.rustfmt.toml new file mode 100644 index 0000000000..f5fe8f3188 --- /dev/null +++ b/rust-bindings/bls-dash-sys/.rustfmt.toml @@ -0,0 +1,17 @@ +unstable_features = true + +blank_lines_lower_bound = 0 +condense_wildcard_suffixes = true +error_on_line_overflow = true +error_on_unformatted = true +format_code_in_doc_comments = true +format_macro_matchers = true +format_strings = true +imports_granularity = "Crate" +normalize_comments = true +normalize_doc_attributes = true +reorder_impl_items = true +group_imports = "StdExternalCrate" +use_field_init_shorthand = true +use_try_shorthand = true +wrap_comments = true diff --git a/rust-bindings/bls-dash-sys/Cargo.toml b/rust-bindings/bls-dash-sys/Cargo.toml new file mode 100644 index 0000000000..c5a04be4de --- /dev/null +++ b/rust-bindings/bls-dash-sys/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "bls-dash-sys" +description = "" +version = "1.2.5" +build = "build.rs" +edition = "2021" + +[features] +default = [] +apple = [] + +[build-dependencies] +cc = "1.0" +bindgen = "0.65.1" +glob ="0.3" diff --git a/rust-bindings/bls-dash-sys/bindings.rs b/rust-bindings/bls-dash-sys/bindings.rs new file mode 100644 index 0000000000..b90527e85f --- /dev/null +++ b/rust-bindings/bls-dash-sys/bindings.rs @@ -0,0 +1,435 @@ +pub type G1Element = *mut ::std::os::raw::c_void; +pub type G2Element = *mut ::std::os::raw::c_void; +pub type PrivateKey = *mut ::std::os::raw::c_void; +pub type CoreMPL = *mut ::std::os::raw::c_void; +pub type BasicSchemeMPL = CoreMPL; +pub type AugSchemeMPL = CoreMPL; +pub type PopSchemeMPL = CoreMPL; +pub type LegacySchemeMPL = CoreMPL; +pub type BIP32ExtendedPrivateKey = *mut ::std::os::raw::c_void; +pub type BIP32ExtendedPublicKey = *mut ::std::os::raw::c_void; +pub type BIP32ChainCode = *mut ::std::os::raw::c_void; + +extern "C" { + pub fn G1ElementSize() -> ::std::os::raw::c_int; + + pub fn G1ElementFromBytes( + data: *const ::std::os::raw::c_void, + legacy: bool, + didErr: *mut bool, + ) -> G1Element; + + pub fn G1ElementGenerator() -> G1Element; + + pub fn G1ElementIsValid(el: G1Element) -> bool; + + pub fn G1ElementGetFingerprint(el: G1Element, legacy: bool) -> u32; + + pub fn G1ElementIsEqual(el1: G1Element, el2: G1Element) -> bool; + + pub fn G1ElementAdd(el1: G1Element, el2: G1Element) -> G1Element; + + pub fn G1ElementMul(el: G1Element, sk: PrivateKey) -> G1Element; + + pub fn G1ElementNegate(el: G1Element) -> G1Element; + + pub fn G1ElementCopy(el: G1Element) -> G1Element; + + pub fn G1ElementSerialize(el: G1Element, legacy: bool) -> *mut ::std::os::raw::c_void; + + pub fn G1ElementFree(el: G1Element); + + pub fn G2ElementSize() -> ::std::os::raw::c_int; + + pub fn G2ElementFromBytes( + data: *const ::std::os::raw::c_void, + legacy: bool, + didErr: *mut bool, + ) -> G2Element; + + pub fn G2ElementGenerator() -> G2Element; + + pub fn G2ElementIsValid(el: G2Element) -> bool; + + pub fn G2ElementIsEqual(el1: G2Element, el2: G2Element) -> bool; + + pub fn G2ElementAdd(el1: G2Element, el2: G2Element) -> G2Element; + + pub fn G2ElementMul(el: G2Element, sk: PrivateKey) -> G2Element; + + pub fn G2ElementNegate(el: G2Element) -> G2Element; + + pub fn G2ElementCopy(el: G2Element) -> G2Element; + + pub fn G2ElementSerialize(el: G2Element, legacy: bool) -> *mut ::std::os::raw::c_void; + + pub fn G2ElementFree(el: G2Element); + + pub fn PrivateKeyFromBytes( + data: *const ::std::os::raw::c_void, + modOrder: bool, + didErr: *mut bool, + ) -> PrivateKey; + + pub fn PrivateKeyFromSeedBIP32(data: *const ::std::os::raw::c_void, len: usize) -> PrivateKey; + + pub fn PrivateKeyAggregate(sks: *mut *mut ::std::os::raw::c_void, len: usize) -> PrivateKey; + + pub fn PrivateKeyGetG1Element(sk: PrivateKey, didErr: *mut bool) -> G1Element; + + pub fn PrivateKeyGetG2Element(sk: PrivateKey, didErr: *mut bool) -> G2Element; + + pub fn PrivateKeyGetG2Power(sk: PrivateKey, el: G2Element) -> G2Element; + + pub fn PrivateKeyIsEqual(sk1: PrivateKey, sk2: PrivateKey) -> bool; + + pub fn PrivateKeySerialize(sk: PrivateKey) -> *mut ::std::os::raw::c_void; + + pub fn PrivateKeyFree(sk: PrivateKey); + + pub fn PrivateKeySizeBytes() -> usize; + + pub fn SecFree(p: *mut ::std::os::raw::c_void); + + pub fn AllocPtrArray(len: usize) -> *mut *mut ::std::os::raw::c_void; + + pub fn SetPtrArray( + arrPtr: *mut *mut ::std::os::raw::c_void, + elemPtr: *mut ::std::os::raw::c_void, + index: ::std::os::raw::c_int, + ); + + pub fn FreePtrArray(inPtr: *mut *mut ::std::os::raw::c_void); + + pub fn GetPtrAtIndex( + arrPtr: *mut *mut ::std::os::raw::c_void, + index: ::std::os::raw::c_int, + ) -> *mut ::std::os::raw::c_void; + + pub fn SecAllocBytes(len: usize) -> *mut u8; + + pub fn GetAddressAtIndex( + ptr: *mut u8, + index: ::std::os::raw::c_int, + ) -> *mut ::std::os::raw::c_void; + + pub fn GetLastErrorMsg() -> *const ::std::os::raw::c_char; + + pub fn CoreMPLKeyGen( + scheme: CoreMPL, + seed: *const ::std::os::raw::c_void, + seedLen: usize, + didErr: *mut bool, + ) -> PrivateKey; + + pub fn CoreMPLSkToG1(scheme: CoreMPL, sk: PrivateKey) -> G1Element; + + pub fn CoreMPLSign( + scheme: CoreMPL, + sk: PrivateKey, + msg: *const ::std::os::raw::c_void, + msgLen: usize, + ) -> G2Element; + + pub fn CoreMPLVerify( + scheme: BasicSchemeMPL, + pk: G1Element, + msg: *const ::std::os::raw::c_void, + msgLen: usize, + sig: G2Element, + ) -> bool; + + pub fn CoreMPLVerifySecure( + scheme: CoreMPL, + pks: *mut *mut ::std::os::raw::c_void, + pksLen: usize, + sig: G2Element, + msg: *const ::std::os::raw::c_void, + msgLen: usize, + ) -> bool; + + pub fn CoreMPLAggregatePubKeys( + scheme: CoreMPL, + pubKeys: *mut *mut ::std::os::raw::c_void, + pkLen: usize, + ) -> G1Element; + + pub fn CoreMPLAggregateSigs( + scheme: CoreMPL, + sigs: *mut *mut ::std::os::raw::c_void, + sigLen: usize, + ) -> G2Element; + + pub fn CoreMPLDeriveChildSk(scheme: CoreMPL, sk: PrivateKey, index: u32) -> PrivateKey; + + pub fn CoreMPLDeriveChildSkUnhardened( + scheme: CoreMPL, + sk: PrivateKey, + index: u32, + ) -> PrivateKey; + + pub fn CoreMPLDeriveChildPkUnhardened(scheme: CoreMPL, sk: G1Element, index: u32) -> G1Element; + + pub fn CoreMPLAggregateVerify( + scheme: CoreMPL, + pks: *mut *mut ::std::os::raw::c_void, + pkLen: usize, + msgs: *mut *mut ::std::os::raw::c_void, + msgLens: *const ::std::os::raw::c_void, + msgLen: usize, + sig: G2Element, + ) -> bool; + + pub fn NewBasicSchemeMPL() -> BasicSchemeMPL; + + pub fn BasicSchemeMPLAggregateVerify( + scheme: BasicSchemeMPL, + pks: *mut *mut ::std::os::raw::c_void, + pksLen: usize, + msgs: *mut *mut ::std::os::raw::c_void, + msgsLens: *const ::std::os::raw::c_void, + msgsLen: usize, + sig: G2Element, + ) -> bool; + + pub fn BasicSchemeMPLFree(scheme: BasicSchemeMPL); + + pub fn NewAugSchemeMPL() -> AugSchemeMPL; + + pub fn AugSchemeMPLSign( + scheme: AugSchemeMPL, + sk: PrivateKey, + msg: *const ::std::os::raw::c_void, + msgLen: usize, + ) -> G2Element; + + pub fn AugSchemeMPLSignPrepend( + scheme: AugSchemeMPL, + sk: PrivateKey, + msg: *const ::std::os::raw::c_void, + msgLen: usize, + prepPk: G1Element, + ) -> G2Element; + + pub fn AugSchemeMPLVerify( + scheme: AugSchemeMPL, + pk: G1Element, + msg: *const ::std::os::raw::c_void, + msgLen: usize, + sig: G2Element, + ) -> bool; + + pub fn AugSchemeMPLAggregateVerify( + scheme: AugSchemeMPL, + pks: *mut *mut ::std::os::raw::c_void, + pksLen: usize, + msgs: *mut *mut ::std::os::raw::c_void, + msgsLens: *const ::std::os::raw::c_void, + msgsLen: usize, + sig: G2Element, + ) -> bool; + + pub fn AugSchemeMPLFree(scheme: AugSchemeMPL); + + pub fn NewPopSchemeMPL() -> PopSchemeMPL; + + pub fn PopSchemeMPLPopProve(scheme: PopSchemeMPL, sk: PrivateKey) -> G2Element; + + pub fn PopSchemeMPLPopVerify(scheme: PopSchemeMPL, pk: G1Element, sig: G2Element) -> bool; + + pub fn PopSchemeMPLFastAggregateVerify( + scheme: PopSchemeMPL, + pks: *mut *mut ::std::os::raw::c_void, + pksLen: usize, + msgs: *const ::std::os::raw::c_void, + msgsLen: usize, + sig: G2Element, + ) -> bool; + + pub fn PopSchemeMPLFree(scheme: PopSchemeMPL); + + pub fn NewLegacySchemeMPL() -> LegacySchemeMPL; + + pub fn LegacySchemeMPLSign( + scheme: LegacySchemeMPL, + sk: PrivateKey, + msg: *const ::std::os::raw::c_void, + msgLen: usize, + ) -> G2Element; + + pub fn LegacySchemeMPLSignPrepend( + scheme: LegacySchemeMPL, + sk: PrivateKey, + msg: *const ::std::os::raw::c_void, + msgLen: usize, + prepPk: G1Element, + ) -> G2Element; + + pub fn LegacySchemeMPLVerify( + scheme: LegacySchemeMPL, + pk: G1Element, + msg: *const ::std::os::raw::c_void, + msgLen: usize, + sig: G2Element, + ) -> bool; + + pub fn LegacySchemeMPLVerifySecure( + scheme: LegacySchemeMPL, + pks: *mut *mut ::std::os::raw::c_void, + pksLen: usize, + sig: G2Element, + msg: *const ::std::os::raw::c_void, + msgLen: usize, + ) -> bool; + + pub fn LegacySchemeMPLAggregateVerify( + scheme: LegacySchemeMPL, + pks: *mut *mut ::std::os::raw::c_void, + pksLen: usize, + msgs: *mut *mut ::std::os::raw::c_void, + msgsLens: *const ::std::os::raw::c_void, + msgsLen: usize, + sig: G2Element, + ) -> bool; + + pub fn LegacySchemeMPLFree(scheme: LegacySchemeMPL); + + pub fn ThresholdPrivateKeyShare( + sks: *mut *mut ::std::os::raw::c_void, + sksLen: usize, + hash: *const ::std::os::raw::c_void, + didErr: *mut bool, + ) -> PrivateKey; + + pub fn ThresholdPrivateKeyRecover( + sks: *mut *mut ::std::os::raw::c_void, + sksLen: usize, + hashes: *mut *mut ::std::os::raw::c_void, + hashesLen: usize, + didErr: *mut bool, + ) -> PrivateKey; + + pub fn ThresholdPublicKeyShare( + pks: *mut *mut ::std::os::raw::c_void, + pksLen: usize, + hash: *const ::std::os::raw::c_void, + didErr: *mut bool, + ) -> G1Element; + + pub fn ThresholdPublicKeyRecover( + pks: *mut *mut ::std::os::raw::c_void, + pksLen: usize, + hashes: *mut *mut ::std::os::raw::c_void, + hashesLen: usize, + didErr: *mut bool, + ) -> G1Element; + + pub fn ThresholdSignatureShare( + sigs: *mut *mut ::std::os::raw::c_void, + sigsLen: usize, + hash: *const ::std::os::raw::c_void, + didErr: *mut bool, + ) -> G2Element; + + pub fn ThresholdSignatureRecover( + sigs: *mut *mut ::std::os::raw::c_void, + sigsLen: usize, + hashes: *mut *mut ::std::os::raw::c_void, + hashesLen: usize, + didErr: *mut bool, + ) -> G2Element; + + pub fn ThresholdSign(sk: PrivateKey, hash: *const ::std::os::raw::c_void) -> G2Element; + + pub fn ThresholdVerify( + pk: G1Element, + hash: *const ::std::os::raw::c_void, + sig: G2Element, + ) -> bool; + + pub fn BIP32ChainCodeSerialize(cc: BIP32ChainCode) -> *mut ::std::os::raw::c_void; + + pub fn BIP32ChainCodeIsEqual(cc1: BIP32ChainCode, cc2: BIP32ChainCode) -> bool; + + pub fn BIP32ChainCodeFree(cc: BIP32ChainCode); + + pub fn BIP32ExtendedPublicKeyFromBytes( + data: *const ::std::os::raw::c_void, + legacy: bool, + didErr: *mut bool, + ) -> BIP32ExtendedPublicKey; + + pub fn BIP32ExtendedPublicKeyPublicChild( + pk: BIP32ExtendedPublicKey, + index: u32, + legacy: bool, + ) -> BIP32ExtendedPublicKey; + + pub fn BIP32ExtendedPublicKeyGetChainCode(pk: BIP32ExtendedPublicKey) -> BIP32ChainCode; + + pub fn BIP32ExtendedPublicKeySerialize( + pk: BIP32ExtendedPublicKey, + legacy: bool, + ) -> *mut ::std::os::raw::c_void; + + pub fn BIP32ExtendedPublicKeyIsEqual( + pk1: BIP32ExtendedPublicKey, + pk2: BIP32ExtendedPublicKey, + ) -> bool; + + pub fn BIP32ExtendedPublicKeyGetPublicKey( + pk: BIP32ExtendedPublicKey, + ) -> *mut ::std::os::raw::c_void; + + pub fn BIP32ExtendedPublicKeyFree(pk: BIP32ExtendedPublicKey); + + pub fn BIP32ExtendedPrivateKeyFromBytes( + data: *const ::std::os::raw::c_void, + didErr: *mut bool, + ) -> BIP32ExtendedPrivateKey; + + pub fn BIP32ExtendedPrivateKeyFromSeed( + data: *const ::std::os::raw::c_void, + len: usize, + didErr: *mut bool, + ) -> BIP32ExtendedPrivateKey; + + pub fn BIP32ExtendedPrivateKeyPrivateChild( + sk: BIP32ExtendedPrivateKey, + index: u32, + legacy: bool, + ) -> BIP32ExtendedPrivateKey; + + pub fn BIP32ExtendedPrivateKeyPublicChild( + sk: BIP32ExtendedPrivateKey, + index: u32, + ) -> BIP32ExtendedPublicKey; + + pub fn BIP32ExtendedPrivateKeyGetChainCode(sk: BIP32ExtendedPrivateKey) -> BIP32ChainCode; + + pub fn BIP32ExtendedPrivateKeySerialize( + sk: BIP32ExtendedPrivateKey, + ) -> *mut ::std::os::raw::c_void; + + pub fn BIP32ExtendedPrivateKeyIsEqual( + sk1: BIP32ExtendedPrivateKey, + sk2: BIP32ExtendedPrivateKey, + ) -> bool; + + pub fn BIP32ExtendedPrivateKeyGetPrivateKey( + sk: BIP32ExtendedPrivateKey, + ) -> *mut ::std::os::raw::c_void; + + pub fn BIP32ExtendedPrivateKeyGetExtendedPublicKey( + sk: BIP32ExtendedPrivateKey, + legacy: bool, + didErr: *mut bool, + ) -> BIP32ExtendedPublicKey; + + pub fn BIP32ExtendedPrivateKeyGetPublicKey( + sk: BIP32ExtendedPrivateKey, + didErr: *mut bool, + ) -> *mut ::std::os::raw::c_void; + + pub fn BIP32ExtendedPrivateKeyFree(sk: BIP32ExtendedPrivateKey); +} diff --git a/rust-bindings/bls-dash-sys/build.rs b/rust-bindings/bls-dash-sys/build.rs new file mode 100644 index 0000000000..cc7cdd2d44 --- /dev/null +++ b/rust-bindings/bls-dash-sys/build.rs @@ -0,0 +1,374 @@ +use std::{env, fs, io, io::Write, path::{Path, PathBuf}, process::{Command, Output}}; + +#[cfg(not(feature = "apple"))] +fn create_cross_cmake_command() -> Command { + let target_arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap(); + + let mut command = if target_arch.eq("wasm32") { + Command::new("emcmake") + } else { + Command::new("cmake") + }; + + if target_arch.eq("wasm32") { + command.arg("cmake"); + } + + command +} + +fn handle_command_output(output: Output) { + io::stdout() + .write_all(&output.stdout) + .expect("should write output"); + + io::stderr() + .write_all(&output.stderr) + .expect("should write output"); + + assert!(output.status.success()); +} + +#[cfg(not(feature = "apple"))] +fn main() { + let target_arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap(); + + // TODO: fix build for wasm32 on MacOS + // errors with `error: linking with `rust-lld` failed: exit status: 1` + if target_arch.eq("wasm32") { + println!("Build for wasm32 is not fully supported"); + return; + } + + let root_path = Path::new("../..") + .canonicalize() + .expect("can't get abs path"); + + let bls_dash_build_path = root_path.join("build"); + let bls_dash_src_path = root_path.join("src"); + let c_bindings_path = root_path.join("rust-bindings/bls-dash-sys/c-bindings"); + + println!("root {}", root_path.display()); + println!("bls_dash_build_path {}", bls_dash_build_path.display()); + println!("bls_dash_src_path {}", bls_dash_src_path.display()); + // println!("c_bindings_path {}", c_bindings_path.display()); + + // Run cmake + + println!("Run cmake:"); + + if bls_dash_build_path.exists() { + fs::remove_dir_all(&bls_dash_build_path).expect("can't clean build directory"); + } + + fs::create_dir_all(&bls_dash_build_path).expect("can't create build directory"); + + let cmake_output = create_cross_cmake_command() + .current_dir(&bls_dash_build_path) + .arg("-DBUILD_BLS_PYTHON_BINDINGS=0") + .arg("-DBUILD_BLS_TESTS=0") + .arg("-DBUILD_BLS_BENCHMARKS=0") + .arg("-DBUILD_BLS_JS_BINDINGS=0") + .arg("..") + .output() + .expect("can't run cmake"); + + handle_command_output(cmake_output); + + // Build deps for bls-signatures + + println!("Build dependencies:"); + + let build_output = Command::new("cmake") + .args(["--build", ".", "--", "-j", "6"]) + .current_dir(&bls_dash_build_path) + .output() + .expect("can't build bls-signatures deps"); + + handle_command_output(build_output); + + // Collect include paths + let include_paths_file_path = bls_dash_build_path.join("include_paths.txt"); + + let include_paths = + fs::read_to_string(include_paths_file_path).expect("should read include paths from file"); + + let mut include_paths: Vec<_> = include_paths + .split(';') + .filter(|path| !path.is_empty()) + .map(|path| PathBuf::from(path)) + .collect(); + + include_paths.extend([ + bls_dash_build_path.join("_deps/relic-src/include"), + bls_dash_build_path.join("_deps/relic-build/include"), + bls_dash_build_path.join("src"), + root_path.join("include/dashbls"), + bls_dash_build_path.join("depends/relic/include"), + bls_dash_build_path.join("depends/mimalloc/include"), + root_path.join("depends/relic/include"), + root_path.join("depends/mimalloc/include"), + bls_dash_src_path.clone(), + ]); + + // Build c binding + + println!("Build C binding:"); + + let mut cc = cc::Build::new(); + + let cpp_files_mask = c_bindings_path.join("**/*.cpp"); + + let cpp_files: Vec<_> = glob::glob(cpp_files_mask.to_str().unwrap()) + .expect("can't get list of cpp files") + .filter_map(Result::ok) + .collect(); + + cc.files(cpp_files) + .includes(&include_paths) + .cpp(true) + .flag_if_supported("-std=c++14"); + + let target_arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap(); + + // Fix homebrew LLVM installation issue + if env::consts::OS == "macos" && target_arch == "wasm32" { + cc.archiver("llvm-ar"); + } + + if target_arch.eq("wasm32") { + cc.flag_if_supported("-ffreestanding") + .define("_LIBCPP_HAS_NO_THREADS", Some("1")); + } + + if !cfg!(debug_assertions) { + cc.opt_level(2); + } + + cc.compile("bls-dash-sys"); + + // // Link dependencies + // println!( + // "cargo:rustc-link-search={}", + // bls_dash_build_path.join("_deps/sodium-build").display() + // ); + + // println!("cargo:rustc-link-lib=static=sodium"); + + println!( + "cargo:rustc-link-search={}", + root_path.join("build/depends/relic/lib").display() + ); + + println!("cargo:rustc-link-lib=static=relic_s"); + + println!( + "cargo:rustc-link-search={}", + root_path.join("build/depends/mimalloc").display() + ); + + println!("cargo:rustc-link-lib=static=mimalloc-secure"); + + println!( + "cargo:rustc-link-search={}", + bls_dash_build_path.join("src").display() + ); + + println!("cargo:rustc-link-lib=static=dashbls"); + + // Link GMP if exists + let gmp_libraries_file_path = bls_dash_build_path.join("gmp_libraries.txt"); + + if gmp_libraries_file_path.exists() { + let gmp_libraries_path = PathBuf::from( + fs::read_to_string(gmp_libraries_file_path) + .expect("should read gmp includes from file"), + ); + + let gmp_libraries_parent_path = gmp_libraries_path + .parent() + .expect("can't get gmp libraries parent dir"); + + println!( + "cargo:rustc-link-search={}", + gmp_libraries_parent_path.display() + ); + + println!("cargo:rustc-link-lib=static=gmp"); + } + + // Generate rust code for c binding to src/lib.rs + // println!("Generate C binding for rust:"); + + // let mut builder = bindgen::Builder::default() + // // .trust_clang_mangling(true) + // // .wasm_import_module_name() + // .size_t_is_usize(true) + // .parse_callbacks(Box::new(bindgen::CargoCallbacks)); + + // let headers_to_process = [ + // "blschia.h", + // "elements.h", + // "privatekey.h", + // "schemes.h", + // "threshold.h", + // "bip32/chaincode.h", + // "bip32/extendedprivatekey.h", + // "bip32/extendedpublickey.h", + // ]; + + // for header in headers_to_process { + // builder = builder.header(c_bindings_path.join(header).to_str().unwrap()) + // } + + // if target_arch == "wasm32" { + // builder = builder.clang_args( + // include_paths + // .iter() + // .map(|path| format!("-I{}", path.display())), + // ); + // } + + // let bindings = builder.generate().expect("Unable to generate bindings"); + + // let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); + + // bindings + // .write_to_file(out_path.join("bindings.rs")) + // .expect("couldn't write bindings"); + + // // Rerun build if files changed + // println!("cargo:rerun-if-changed={}", c_bindings_path.display()); + println!("cargo:rerun-if-changed={}", bls_dash_src_path.display()); +} + +// fn main() { +// let target = env::var("TARGET").unwrap(); +// println!("Building bls-signatures for apple target: {}", target); +// let root_path = Path::new("../..") +// .canonicalize() +// .expect("can't get abs path"); +// let bls_dash_build_path = root_path.join("build"); +// let bls_dash_src_path = root_path.join("src"); +// let artefacts_path = bls_dash_build_path.join("artefacts"); +// let target_path = artefacts_path.join(&target); +// let script = root_path.join("apple.rust.single.sh"); +// if bls_dash_build_path.exists() { +// fs::remove_dir_all(&bls_dash_build_path).expect("can't clean build directory"); +// } +// fs::create_dir_all(&bls_dash_build_path).expect("can't create build directory"); +// let output = Command::new("sh") +// .current_dir(&root_path) +// .arg(script) +// .arg(target) +// .output() +// .expect("Failed to execute the shell script"); +// handle_command_output(output); +// let library_path = target_path.join("libbls.a"); +// if !fs::metadata(&library_path).is_ok() { +// panic!("Library file not found: {}", library_path.display()); +// } +// println!("cargo:rustc-link-search={}", target_path.display()); +// println!("cargo:rustc-link-lib=static=gmp"); +// println!("cargo:rustc-link-lib=static=sodium"); +// println!("cargo:rustc-link-lib=static=relic_s"); +// println!("cargo:rustc-link-search={}", bls_dash_build_path.join("src").display()); +// println!("cargo:rustc-link-lib=static=bls"); +// println!("cargo:rerun-if-changed={}", bls_dash_src_path.display()); +// } + +#[cfg(feature = "apple")] +fn main() { + let target_arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap(); + + // TODO: fix build for wasm32 on MacOS + // errors with `error: linking with `rust-lld` failed: exit status: 1` + if target_arch.eq("wasm32") { + println!("Build for wasm32 is not fully supported"); + return; + } + + + let target = env::var("TARGET").unwrap(); + println!("Building bls-signatures for apple target: {}", target); + let root_path = Path::new("../..") + .canonicalize() + .expect("can't get abs path"); + let bls_dash_build_path = root_path.join("build"); + let bls_dash_src_path = root_path.join("src"); + let bls_dash_src_include_path = root_path.join("include/dashbls"); + let c_bindings_path = root_path.join("rust-bindings/bls-dash-sys/c-bindings"); + let artefacts_path = bls_dash_build_path.join("artefacts"); + let target_path = artefacts_path.join(&target); + let script = root_path.join("apple.rust.deps.sh"); + if bls_dash_build_path.exists() { + fs::remove_dir_all(&bls_dash_build_path).expect("can't clean build directory"); + } + fs::create_dir_all(&bls_dash_build_path).expect("can't create build directory"); + let output = Command::new("sh") + .current_dir(&root_path) + .arg(script) + .arg(target.as_str()) + .output() + .expect("Failed to execute the shell script"); + handle_command_output(output); + let (arch, platform) = match target.as_str() { + "x86_64-apple-ios" => ("x86_64", "iphonesimulator"), + "aarch64-apple-ios" => ("arm64", "iphoneos"), + "aarch64-apple-ios-sim" => ("arm64", "iphonesimulator"), + "x86_64-apple-darwin" => ("x86_64", "macosx"), + "aarch64-apple-darwin" => ("arm64", "macosx"), + _ => panic!("Target {} not supported", target.as_str()) + }; + env::set_var("IPHONEOS_DEPLOYMENT_TARGET", "13.0"); + + // Collect include paths + let include_paths_file_path = bls_dash_build_path.join("include_paths.txt"); + + let include_paths = + fs::read_to_string(include_paths_file_path).expect("should read include paths from file"); + + let mut include_paths: Vec<_> = include_paths + .split(';') + .filter(|path| !path.is_empty()) + .map(|path| PathBuf::from(path)) + .collect(); + + include_paths.extend([ + bls_dash_build_path.join(format!("relic-{}-{}/_deps/relic-src/include", platform, arch)), + bls_dash_build_path.join(format!("relic-{}-{}/_deps/relic-build/include", platform, arch)), + bls_dash_build_path.join("contrib/relic/src"), + root_path.join("src"), + root_path.join("include/dashbls"), + root_path.join("depends/relic/include"), + root_path.join("depends/mimalloc/include"), + root_path.join("depends/catch2/include"), + bls_dash_src_path.clone(), + bls_dash_src_include_path.clone() + ]); + + let cpp_files: Vec<_> = glob::glob(c_bindings_path.join("**/*.cpp").to_str().unwrap()) + .expect("can't get list of cpp files") + .filter_map(Result::ok) + .collect(); + + let mut cc = cc::Build::new(); + cc.files(cpp_files) + .includes(&include_paths) + .cpp(true) + .flag("-Wno-unused-parameter") + .flag("-Wno-sign-compare") + .flag("-Wno-delete-non-abstract-non-virtual-dtor") + .flag("-std=c++14"); + + cc.compile("dashbls"); + + println!("cargo:rustc-link-search={}", target_path.display()); + println!("cargo:rustc-link-lib=static=gmp"); + // println!("cargo:rustc-link-lib=static=sodium"); + // println!("cargo:rustc-link-lib=static=relic_s"); + println!("cargo:rustc-link-lib=static=bls"); + println!("cargo:rustc-link-search={}", bls_dash_src_path.display()); + println!("cargo:rustc-link-lib=static=dashbls"); + println!("cargo:rerun-if-changed={}", bls_dash_src_path.display()); +} diff --git a/rust-bindings/bls-dash-sys/c-bindings/bip32/chaincode.cpp b/rust-bindings/bls-dash-sys/c-bindings/bip32/chaincode.cpp new file mode 100644 index 0000000000..177c4d7371 --- /dev/null +++ b/rust-bindings/bls-dash-sys/c-bindings/bip32/chaincode.cpp @@ -0,0 +1,25 @@ +#include +#include "bls.hpp" +#include "chaincode.h" + +void* BIP32ChainCodeSerialize(const BIP32ChainCode cc) +{ + const bls::ChainCode* ccPtr = (bls::ChainCode*)cc; + const std::vector serialized = ccPtr->Serialize(); + uint8_t* buffer = (uint8_t*)malloc(bls::ChainCode::SIZE); + memcpy(buffer, serialized.data(), bls::ChainCode::SIZE); + return (void*)buffer; +} + +bool BIP32ChainCodeIsEqual(const BIP32ChainCode cc1, const BIP32ChainCode cc2) +{ + const bls::ChainCode* cc1Ptr = (bls::ChainCode*)cc1; + const bls::ChainCode* cc2Ptr = (bls::ChainCode*)cc2; + return *cc1Ptr == *cc2Ptr; +} + +void BIP32ChainCodeFree(const BIP32ChainCode cc) +{ + const bls::ChainCode* ccPtr = (bls::ChainCode*)cc; + delete ccPtr; +} diff --git a/rust-bindings/bls-dash-sys/c-bindings/bip32/chaincode.h b/rust-bindings/bls-dash-sys/c-bindings/bip32/chaincode.h new file mode 100644 index 0000000000..688cf3f51e --- /dev/null +++ b/rust-bindings/bls-dash-sys/c-bindings/bip32/chaincode.h @@ -0,0 +1,21 @@ +#ifndef BIP32CHAINCODE_H_ +#define BIP32CHAINCODE_H_ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void* BIP32ChainCode; + +void* BIP32ChainCodeSerialize(const BIP32ChainCode cc); +bool BIP32ChainCodeIsEqual(const BIP32ChainCode cc1, const BIP32ChainCode cc2); +void BIP32ChainCodeFree(const BIP32ChainCode cc); + +#ifdef __cplusplus +} +#endif +#endif // BIP32CHAINCODE_H_ \ No newline at end of file diff --git a/rust-bindings/bls-dash-sys/c-bindings/bip32/extendedprivatekey.cpp b/rust-bindings/bls-dash-sys/c-bindings/bip32/extendedprivatekey.cpp new file mode 100644 index 0000000000..541f5f992c --- /dev/null +++ b/rust-bindings/bls-dash-sys/c-bindings/bip32/extendedprivatekey.cpp @@ -0,0 +1,128 @@ +#include "extendedprivatekey.h" + +#include + +#include "../blschia.h" +#include "../error.h" +#include "bls.hpp" + +BIP32ExtendedPrivateKey BIP32ExtendedPrivateKeyFromBytes(const void* data, bool* didErr) +{ + bls::ExtendedPrivateKey* el = nullptr; + try { + el = new bls::ExtendedPrivateKey(bls::ExtendedPrivateKey::FromBytes( + bls::Bytes((uint8_t*)(data), bls::ExtendedPrivateKey::SIZE))); + } catch (const std::exception& ex) { + gErrMsg = ex.what(); + *didErr = true; + return nullptr; + } + *didErr = false; + return el; +} + +BIP32ExtendedPrivateKey BIP32ExtendedPrivateKeyFromSeed(const void* data, const size_t len, bool* didErr) +{ + bls::ExtendedPrivateKey* el = nullptr; + try { + el = new bls::ExtendedPrivateKey(bls::ExtendedPrivateKey::FromSeed( + bls::Bytes((uint8_t*)(data), len))); + } catch (const std::exception& ex) { + gErrMsg = ex.what(); + *didErr = true; + return nullptr; + } + *didErr = false; + return el; +} + +BIP32ExtendedPrivateKey BIP32ExtendedPrivateKeyPrivateChild( + const BIP32ExtendedPrivateKey sk, + const uint32_t index, + const bool legacy) +{ + const bls::ExtendedPrivateKey* skPtr = (bls::ExtendedPrivateKey*)sk; + return new bls::ExtendedPrivateKey(skPtr->PrivateChild(index, legacy)); +} + +BIP32ExtendedPublicKey BIP32ExtendedPrivateKeyPublicChild( + const BIP32ExtendedPrivateKey sk, + const uint32_t index) +{ + const bls::ExtendedPrivateKey* skPtr = (bls::ExtendedPrivateKey*)sk; + return new bls::ExtendedPublicKey(skPtr->PublicChild(index)); +} + +BIP32ChainCode BIP32ExtendedPrivateKeyGetChainCode(const BIP32ExtendedPrivateKey sk) +{ + const bls::ExtendedPrivateKey* skPtr = (bls::ExtendedPrivateKey*)sk; + return new bls::ChainCode(skPtr->GetChainCode()); +} + +void* BIP32ExtendedPrivateKeySerialize(const BIP32ExtendedPrivateKey sk) +{ + const bls::ExtendedPrivateKey* skPtr = (bls::ExtendedPrivateKey*)sk; + uint8_t* buffer = + bls::Util::SecAlloc(bls::ExtendedPrivateKey::SIZE); + skPtr->Serialize(buffer); + + return (void*)buffer; +} + +bool BIP32ExtendedPrivateKeyIsEqual( + const BIP32ExtendedPrivateKey sk1, + const BIP32ExtendedPrivateKey sk2) +{ + const bls::ExtendedPrivateKey* sk1Ptr = (bls::ExtendedPrivateKey*)sk1; + const bls::ExtendedPrivateKey* sk2Ptr = (bls::ExtendedPrivateKey*)sk2; + return *sk1Ptr == *sk2Ptr; +} + +void* BIP32ExtendedPrivateKeyGetPrivateKey(const BIP32ExtendedPrivateKey sk) +{ + bls::ExtendedPrivateKey* skPtr = (bls::ExtendedPrivateKey*)sk; + return new bls::PrivateKey(skPtr->GetPrivateKey()); +} + +void* BIP32ExtendedPrivateKeyGetPublicKey( + const BIP32ExtendedPrivateKey sk, + bool* didErr) +{ + bls::ExtendedPrivateKey* skPtr = (bls::ExtendedPrivateKey*)sk; + bls::G1Element* el = nullptr; + try { + el = new bls::G1Element(skPtr->GetPublicKey()); + *didErr = false; + } catch (const std::exception& ex) { + // set err + gErrMsg = ex.what(); + *didErr = true; + return nullptr; + } + return el; +} + +BIP32ExtendedPublicKey BIP32ExtendedPrivateKeyGetExtendedPublicKey( + const BIP32ExtendedPrivateKey sk, + const bool legacy, + bool* didErr) +{ + bls::ExtendedPrivateKey* skPtr = (bls::ExtendedPrivateKey*)sk; + bls::ExtendedPublicKey* pk = nullptr; + try { + pk = new bls::ExtendedPublicKey(skPtr->GetExtendedPublicKey(legacy)); + *didErr = false; + } catch (const std::exception& ex) { + // set err + gErrMsg = ex.what(); + *didErr = true; + return nullptr; + } + return pk; +} + +void BIP32ExtendedPrivateKeyFree(const BIP32ExtendedPrivateKey sk) +{ + const bls::ExtendedPrivateKey* skPtr = (bls::ExtendedPrivateKey*)sk; + delete skPtr; +} diff --git a/rust-bindings/bls-dash-sys/c-bindings/bip32/extendedprivatekey.h b/rust-bindings/bls-dash-sys/c-bindings/bip32/extendedprivatekey.h new file mode 100644 index 0000000000..18ca3c28f3 --- /dev/null +++ b/rust-bindings/bls-dash-sys/c-bindings/bip32/extendedprivatekey.h @@ -0,0 +1,48 @@ +#ifndef BIP32EXTENDEDPRIVATEKEY_H_ +#define BIP32EXTENDEDPRIVATEKEY_H_ + +#include +#include +#include + +#include "extendedpublickey.h" +#include "chaincode.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void* BIP32ExtendedPrivateKey; + +// ExtendedPrivateKey +BIP32ExtendedPrivateKey BIP32ExtendedPrivateKeyFromBytes( + const void* data, + bool* didErr); +BIP32ExtendedPrivateKey BIP32ExtendedPrivateKeyFromSeed(const void* data, const size_t len, bool* didErr); +BIP32ExtendedPrivateKey BIP32ExtendedPrivateKeyPrivateChild( + const BIP32ExtendedPrivateKey sk, + const uint32_t index, + const bool legacy); +BIP32ExtendedPublicKey BIP32ExtendedPrivateKeyPublicChild( + const BIP32ExtendedPrivateKey sk, + const uint32_t index); +BIP32ChainCode BIP32ExtendedPrivateKeyGetChainCode(const BIP32ExtendedPrivateKey sk); +void* BIP32ExtendedPrivateKeySerialize(const BIP32ExtendedPrivateKey sk); +bool BIP32ExtendedPrivateKeyIsEqual( + const BIP32ExtendedPrivateKey sk1, + const BIP32ExtendedPrivateKey sk2); +void* BIP32ExtendedPrivateKeyGetPrivateKey(const BIP32ExtendedPrivateKey sk); +BIP32ExtendedPublicKey BIP32ExtendedPrivateKeyGetExtendedPublicKey( + const BIP32ExtendedPrivateKey sk, + const bool legacy, + bool* didErr); +void* BIP32ExtendedPrivateKeyGetPublicKey( + const BIP32ExtendedPrivateKey sk, + bool* didErr); +void BIP32ExtendedPrivateKeyFree(const BIP32ExtendedPrivateKey sk); + +#ifdef __cplusplus +} +#endif +#endif // BIP32EXTENDEDPRIVATEKEY_H_ diff --git a/rust-bindings/bls-dash-sys/c-bindings/bip32/extendedpublickey.cpp b/rust-bindings/bls-dash-sys/c-bindings/bip32/extendedpublickey.cpp new file mode 100644 index 0000000000..703c32e021 --- /dev/null +++ b/rust-bindings/bls-dash-sys/c-bindings/bip32/extendedpublickey.cpp @@ -0,0 +1,72 @@ +#include "extendedpublickey.h" + +#include + +#include "../blschia.h" +#include "../error.h" +#include "bls.hpp" + +BIP32ExtendedPublicKey BIP32ExtendedPublicKeyFromBytes( + const void* data, + const bool legacy, + bool* didErr) +{ + bls::ExtendedPublicKey* el = nullptr; + try { + el = new bls::ExtendedPublicKey(bls::ExtendedPublicKey::FromBytes( + bls::Bytes((uint8_t*)(data), bls::ExtendedPublicKey::SIZE), + legacy)); + } catch (const std::exception& ex) { + gErrMsg = ex.what(); + *didErr = true; + return nullptr; + } + *didErr = false; + return el; +} + +BIP32ExtendedPublicKey BIP32ExtendedPublicKeyPublicChild( + const BIP32ExtendedPublicKey pk, + const uint32_t index, + const bool legacy) +{ + const bls::ExtendedPublicKey* pkPtr = (bls::ExtendedPublicKey*)pk; + return new bls::ExtendedPublicKey(pkPtr->PublicChild(index, legacy)); +} + +BIP32ChainCode BIP32ExtendedPublicKeyGetChainCode(const BIP32ExtendedPublicKey pk) +{ + const bls::ExtendedPublicKey* pkPtr = (bls::ExtendedPublicKey*)pk; + return new bls::ChainCode(pkPtr->GetChainCode()); +} + +void* BIP32ExtendedPublicKeyGetPublicKey(const BIP32ExtendedPublicKey pk) { + bls::ExtendedPublicKey* pkPtr = (bls::ExtendedPublicKey*)pk; + return new bls::G1Element(pkPtr->GetPublicKey()); +} + +void* BIP32ExtendedPublicKeySerialize( + const BIP32ExtendedPublicKey pk, + const bool legacy) +{ + const bls::ExtendedPublicKey* pkPtr = (bls::ExtendedPublicKey*)pk; + const std::vector serialized = pkPtr->Serialize(legacy); + uint8_t* buffer = (uint8_t*)malloc(bls::ExtendedPublicKey::SIZE); + memcpy(buffer, serialized.data(), bls::ExtendedPublicKey::SIZE); + return (void*)buffer; +} + +bool BIP32ExtendedPublicKeyIsEqual( + const BIP32ExtendedPublicKey pk1, + const BIP32ExtendedPublicKey pk2) +{ + const bls::ExtendedPublicKey* pk1Ptr = (bls::ExtendedPublicKey*)pk1; + const bls::ExtendedPublicKey* pk2Ptr = (bls::ExtendedPublicKey*)pk2; + return *pk1Ptr == *pk2Ptr; +} + +void BIP32ExtendedPublicKeyFree(const BIP32ExtendedPublicKey pk) +{ + const bls::ExtendedPublicKey* pkPtr = (bls::ExtendedPublicKey*)pk; + delete pkPtr; +} diff --git a/rust-bindings/bls-dash-sys/c-bindings/bip32/extendedpublickey.h b/rust-bindings/bls-dash-sys/c-bindings/bip32/extendedpublickey.h new file mode 100644 index 0000000000..51465cae03 --- /dev/null +++ b/rust-bindings/bls-dash-sys/c-bindings/bip32/extendedpublickey.h @@ -0,0 +1,38 @@ +#ifndef BIP32EXTENDEDPUBLICKEY_H_ +#define BIP32EXTENDEDPUBLICKEY_H_ + +#include +#include +#include + +#include "chaincode.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void* BIP32ExtendedPublicKey; + +// ExtendedPublicKey +BIP32ExtendedPublicKey BIP32ExtendedPublicKeyFromBytes( + const void* data, + const bool legacy, + bool* didErr); +BIP32ExtendedPublicKey BIP32ExtendedPublicKeyPublicChild( + const BIP32ExtendedPublicKey pk, + const uint32_t index, + const bool legacy); +BIP32ChainCode BIP32ExtendedPublicKeyGetChainCode(const BIP32ExtendedPublicKey pk); +void* BIP32ExtendedPublicKeyGetPublicKey(const BIP32ExtendedPublicKey pk); +void* BIP32ExtendedPublicKeySerialize( + const BIP32ExtendedPublicKey pk, + const bool legacy); +bool BIP32ExtendedPublicKeyIsEqual( + const BIP32ExtendedPublicKey pk1, + const BIP32ExtendedPublicKey pk2); +void BIP32ExtendedPublicKeyFree(const BIP32ExtendedPublicKey pk); + +#ifdef __cplusplus +} +#endif +#endif // BIP32EXTENDEDPUBLICKEY_H_ diff --git a/rust-bindings/bls-dash-sys/c-bindings/blschia.cpp b/rust-bindings/bls-dash-sys/c-bindings/blschia.cpp new file mode 100644 index 0000000000..2b3c274dc4 --- /dev/null +++ b/rust-bindings/bls-dash-sys/c-bindings/blschia.cpp @@ -0,0 +1,56 @@ +// Copyright (c) 2021 The Dash Core developers + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 + +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include +#include "bls.hpp" +#include "error.h" +#include "blschia.h" + +// TODO: Revisit + +std::string gErrMsg; + +void SecFree(void *p) { + bls::Util::SecFree(p); +} + +void** AllocPtrArray(size_t len) { + // caller to free + return (void**)bls::Util::SecAlloc(sizeof(void*) * len); +} + +void SetPtrArray(void** arrPtr, void* elemPtr, int index) { + arrPtr[index] = elemPtr; +} + +void FreePtrArray(void** inPtr) { + bls::Util::SecFree(inPtr); +} + +void* GetPtrAtIndex(void** arrPtr, int index) { + return arrPtr[index]; +} + +uint8_t* SecAllocBytes(size_t len) { + return (uint8_t*)bls::Util::SecAlloc(sizeof(uint8_t) * len); +} + +void* GetAddressAtIndex(uint8_t* ptr, int index) { + return (void*)&ptr[index]; +} + +const char* GetLastErrorMsg() { + return gErrMsg.c_str(); +} diff --git a/rust-bindings/bls-dash-sys/c-bindings/blschia.h b/rust-bindings/bls-dash-sys/c-bindings/blschia.h new file mode 100644 index 0000000000..ebc3b518dc --- /dev/null +++ b/rust-bindings/bls-dash-sys/c-bindings/blschia.h @@ -0,0 +1,46 @@ +// Copyright (c) 2021 The Dash Core developers + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 + +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef BLSCHIA_H_ +#define BLSCHIA_H_ +#include +#include +#include "privatekey.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// Export the BLS SecFree method +void SecFree(void *p); + +typedef void** carr; + +// Additional C++ helper funcs for allocations +void** AllocPtrArray(size_t len); +void SetPtrArray(void **arrPtr, void *elemPtr, int index); +void FreePtrArray(void **inPtr); +void* GetPtrAtIndex(void **arrPtr, int index); + +// Allocates an array of bytes with size of passed in len argument +uint8_t* SecAllocBytes(size_t len); + +void* GetAddressAtIndex(uint8_t *ptr, int index); + +const char* GetLastErrorMsg(); + +#ifdef __cplusplus +} +#endif +#endif // BLSCHIA_H_ diff --git a/rust-bindings/bls-dash-sys/c-bindings/elements.cpp b/rust-bindings/bls-dash-sys/c-bindings/elements.cpp new file mode 100644 index 0000000000..5214bc4fc9 --- /dev/null +++ b/rust-bindings/bls-dash-sys/c-bindings/elements.cpp @@ -0,0 +1,162 @@ +// Copyright (c) 2021 The Dash Core developers + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 + +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include "bls.hpp" +#include "blschia.h" +#include "error.h" +#include "elements.h" + +// G1Element +int G1ElementSize() { + return bls::G1Element::SIZE; +} + +G1Element G1ElementFromBytes(const void* data, bool legacy, bool* didErr) { + bls::G1Element* el = nullptr; + try { + el = new bls::G1Element( + bls::G1Element::FromBytes(bls::Bytes((uint8_t*)(data), bls::G1Element::SIZE), legacy) + ); + } catch(const std::exception& ex) { + gErrMsg = ex.what(); + *didErr = true; + return nullptr; + } + *didErr = false; + return el; +} + +G1Element G1ElementGenerator() { + return new bls::G1Element(bls::G1Element::Generator()); +} + +bool G1ElementIsValid(const G1Element el) { + const bls::G1Element* elPtr = (bls::G1Element*)el; + return elPtr->IsValid(); +} + +uint32_t G1ElementGetFingerprint(const G1Element el, const bool legacy) { + const bls::G1Element* elPtr = (bls::G1Element*)el; + return elPtr->GetFingerprint(legacy); +} + +void* G1ElementSerialize(const G1Element el, const bool legacy) { + const bls::G1Element* elPtr = (bls::G1Element*)el; + const std::vector serialized = elPtr->Serialize(legacy); + uint8_t* buffer = (uint8_t*)malloc(bls::G1Element::SIZE); + memcpy(buffer, serialized.data(), bls::G1Element::SIZE); + return (void*)buffer; +} + +bool G1ElementIsEqual(const G1Element el1, const G1Element el2) { + const bls::G1Element* el1Ptr = (bls::G1Element*)el1; + const bls::G1Element* el2Ptr = (bls::G1Element*)el2; + return *el1Ptr == *el2Ptr; +} + +G1Element G1ElementAdd(const G1Element el1, const G1Element el2) { + const bls::G1Element* el1Ptr = (bls::G1Element*)el1; + const bls::G1Element* el2Ptr = (bls::G1Element*)el2; + return new bls::G1Element((*el1Ptr) + (*el2Ptr)); +} + +G1Element G1ElementMul(const G1Element el, const PrivateKey sk) { + const bls::G1Element* elPtr = (bls::G1Element*)el; + const bls::PrivateKey* skPtr = (bls::PrivateKey*)sk; + return new bls::G1Element(*elPtr * *skPtr); +} + +G1Element G1ElementNegate(const G1Element el) { + const bls::G1Element* elPtr = (bls::G1Element*)el; + return new bls::G1Element(elPtr->Negate()); +} + +G1Element G1ElementCopy(const G1Element el) { + return new bls::G1Element(((bls::G1Element*)el)->Copy()); +} + +void G1ElementFree(const G1Element el) { + const bls::G1Element* elPtr = (bls::G1Element*)el; + delete elPtr; +} + +// G2Element +int G2ElementSize() { + return bls::G2Element::SIZE; +} + +G2Element G2ElementFromBytes(const void* data, const bool legacy, bool* didErr) { + bls::G2Element* el = nullptr; + try { + el = new bls::G2Element( + bls::G2Element::FromBytes(bls::Bytes((uint8_t*)data, bls::G2Element::SIZE), legacy) + ); + *didErr = false; + } catch(const std::exception& ex) { + gErrMsg = ex.what(); + *didErr = true; + return nullptr; + } + return el; +} + +G2Element G2ElementGenerator() { + return new bls::G2Element(bls::G2Element::Generator()); +} + +bool G2ElementIsValid(const G2Element el) { + const bls::G2Element* elPtr = (bls::G2Element*)el; + return elPtr->IsValid(); +} + +void* G2ElementSerialize(const G2Element el, const bool legacy) { + const bls::G2Element* elPtr = (bls::G2Element*)el; + const std::vector serialized = elPtr->Serialize(legacy); + uint8_t* buffer = (uint8_t*)malloc(bls::G2Element::SIZE); + memcpy(buffer, serialized.data(), bls::G2Element::SIZE); + return (void*)buffer; +} + +bool G2ElementIsEqual(const G2Element el1, const G2Element el2) { + const bls::G2Element* el1Ptr = (bls::G2Element*)el1; + const bls::G2Element* el2Ptr = (bls::G2Element*)el2; + return *el1Ptr == *el2Ptr; +} + +G2Element G2ElementAdd(const G2Element el1, const G2Element el2) { + bls::G2Element* el1Ptr = (bls::G2Element*)el1; + bls::G2Element* el2Ptr = (bls::G2Element*)el2; + return new bls::G2Element(*el1Ptr + *el2Ptr); +} + +G2Element G2ElementMul(const G2Element el, const PrivateKey sk) { + const bls::G2Element* elPtr = (bls::G2Element*)el; + const bls::PrivateKey* skPtr = (bls::PrivateKey*)sk; + return new bls::G2Element(*elPtr * *skPtr); +} + +G2Element G2ElementNegate(const G2Element el) { + const bls::G2Element* elPtr = (bls::G2Element*)el; + return new bls::G2Element(elPtr->Negate()); +} + +G2Element G2ElementCopy(const G1Element el) { + return new bls::G2Element(((bls::G2Element*)el)->Copy()); +} + +void G2ElementFree(const G2Element el) { + bls::G2Element* elPtr = (bls::G2Element*)el; + delete elPtr; +} diff --git a/rust-bindings/bls-dash-sys/c-bindings/elements.h b/rust-bindings/bls-dash-sys/c-bindings/elements.h new file mode 100644 index 0000000000..fa1b5ae581 --- /dev/null +++ b/rust-bindings/bls-dash-sys/c-bindings/elements.h @@ -0,0 +1,58 @@ +// Copyright (c) 2021 The Dash Core developers + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 + +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef ELEMENTS_H_ +#define ELEMENTS_H_ +#include +#include +#include +#ifdef __cplusplus +extern "C" { +#endif + +typedef void* G1Element; +typedef void* G2Element; +typedef void* PrivateKey; + +// G1Element +int G1ElementSize(); +G1Element G1ElementFromBytes(const void* data, const bool legacy, bool* didErr); +G1Element G1ElementGenerator(); +bool G1ElementIsValid(const G1Element el); +uint32_t G1ElementGetFingerprint(const G1Element el, const bool legacy); +bool G1ElementIsEqual(const G1Element el1, const G1Element el2); +G1Element G1ElementAdd(const G1Element el1, const G1Element el2); +G1Element G1ElementMul(const G1Element el, const PrivateKey sk); +G1Element G1ElementNegate(const G1Element el); +G1Element G1ElementCopy(const G1Element el); +void* G1ElementSerialize(const G1Element el, const bool legacy); +void G1ElementFree(const G1Element el); + +// G2Element +int G2ElementSize(); +G2Element G2ElementFromBytes(const void* data, const bool legacy, bool* didErr); +G2Element G2ElementGenerator(); +bool G2ElementIsValid(const G2Element el); +bool G2ElementIsEqual(const G2Element el1, const G2Element el2); +G2Element G2ElementAdd(const G2Element el1, const G2Element el2); +G2Element G2ElementMul(const G2Element el, const PrivateKey sk); +G2Element G2ElementNegate(const G2Element el); +G2Element G2ElementCopy(const G2Element el); +void* G2ElementSerialize(const G2Element el, const bool legacy); +void G2ElementFree(const G2Element el); + +#ifdef __cplusplus +} +#endif +#endif // ELEMENTS_H_ diff --git a/rust-bindings/bls-dash-sys/c-bindings/error.h b/rust-bindings/bls-dash-sys/c-bindings/error.h new file mode 100644 index 0000000000..57525b77fa --- /dev/null +++ b/rust-bindings/bls-dash-sys/c-bindings/error.h @@ -0,0 +1,21 @@ +// Copyright (c) 2020 The Dash Core developers + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 + +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef ERROR_H_ +#define ERROR_H_ +#include + +extern std::string gErrMsg; + +#endif // ERROR_H_ diff --git a/rust-bindings/bls-dash-sys/c-bindings/privatekey.cpp b/rust-bindings/bls-dash-sys/c-bindings/privatekey.cpp new file mode 100644 index 0000000000..4e1d0df346 --- /dev/null +++ b/rust-bindings/bls-dash-sys/c-bindings/privatekey.cpp @@ -0,0 +1,120 @@ +// Copyright (c) 2021 The Dash Core developers + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 + +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include "bls.hpp" +#include "privatekey.h" +#include "blschia.h" +#include "error.h" +#include "utils.hpp" + +// private key bindings implementation +PrivateKey PrivateKeyFromBytes(const void* data, const bool modOrder, bool* didErr) { + bls::PrivateKey* skPtr = nullptr; + try { + skPtr = new bls::PrivateKey( + bls::PrivateKey::FromBytes( + bls::Bytes((uint8_t*)data, bls::PrivateKey::PRIVATE_KEY_SIZE), + modOrder + ) + ); + } catch (const std::exception& ex) { + // set err + gErrMsg = ex.what(); + *didErr = true; + return nullptr; + } + *didErr = false; + return skPtr; +} + +PrivateKey PrivateKeyFromSeedBIP32(const void* data, const size_t len) { + return new bls::PrivateKey( + bls::PrivateKey::FromSeedBIP32(bls::Bytes((uint8_t*)data, len)) + ); +} + +PrivateKey PrivateKeyAggregate(void** sks, const size_t len) { + return new bls::PrivateKey( + bls::PrivateKey::Aggregate(toBLSVector(sks, len)) + ); +} + +void* PrivateKeySerialize(const PrivateKey sk) { + const bls::PrivateKey* skPtr = (bls::PrivateKey*)sk; + uint8_t* buffer = bls::Util::SecAlloc(bls::PrivateKey::PRIVATE_KEY_SIZE); + skPtr->Serialize(buffer); + + return (void*)buffer; +} + +size_t PrivateKeySizeBytes() { + return bls::PrivateKey::PRIVATE_KEY_SIZE; +} + +bool PrivateKeyIsEqual(const PrivateKey sk1, const PrivateKey sk2) { + const bls::PrivateKey* sk1Ptr = (bls::PrivateKey*)sk1; + const bls::PrivateKey* sk2Ptr = (bls::PrivateKey*)sk2; + return *sk1Ptr == *sk2Ptr; +} + +G1Element PrivateKeyGetG1Element(const PrivateKey sk, bool* didErr) { + bls::PrivateKey* skPtr = (bls::PrivateKey*)sk; + bls::G1Element* el = nullptr; + try { + el = new bls::G1Element(skPtr->GetG1Element()); + *didErr = false; + } catch (const std::exception& ex) { + // set err + gErrMsg = ex.what(); + *didErr = true; + return nullptr; + } + return el; +} + +G2Element PrivateKeyGetG2Element(const PrivateKey sk, bool* didErr) { + bls::PrivateKey* skPtr = (bls::PrivateKey*)sk; + bls::G2Element* el = nullptr; + try { + el = new bls::G2Element(skPtr->GetG2Element()); + *didErr = false; + } catch (const std::exception& ex) { + // set err + gErrMsg = ex.what(); + *didErr = true; + return nullptr; + } + return el; +} + +G2Element PrivateKeyGetG2Power(const PrivateKey sk, const G2Element el) { + const bls::PrivateKey* skPtr = (bls::PrivateKey*)sk; + const bls::G2Element* elPtr = (bls::G2Element*)el; + return new bls::G2Element(skPtr->GetG2Power(*elPtr)); +} + +G2Element PrivateKeySignG2(const PrivateKey sk, + uint8_t* msg, + const size_t len, + const uint8_t* dst, + const size_t dstLen) { + const bls::PrivateKey* skPtr = (bls::PrivateKey*)sk; + return new bls::G2Element(skPtr->SignG2(msg, len, dst, dstLen)); +} + +void PrivateKeyFree(PrivateKey sk) { + bls::PrivateKey* skPtr = (bls::PrivateKey*)sk; + delete skPtr; +} diff --git a/rust-bindings/bls-dash-sys/c-bindings/privatekey.h b/rust-bindings/bls-dash-sys/c-bindings/privatekey.h new file mode 100644 index 0000000000..147e1a618f --- /dev/null +++ b/rust-bindings/bls-dash-sys/c-bindings/privatekey.h @@ -0,0 +1,40 @@ +// Copyright (c) 2021 The Dash Core developers + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 + +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef PRIVATEKEY_H_ +#define PRIVATEKEY_H_ +#include +#include +#include "elements.h" +#ifdef __cplusplus +extern "C" { +#endif + +typedef void* PrivateKey; + +PrivateKey PrivateKeyFromBytes(const void* data, const bool modOrder, bool* didErr); +PrivateKey PrivateKeyFromSeedBIP32(const void* data, const size_t len); +PrivateKey PrivateKeyAggregate(void** sks, const size_t len); +G1Element PrivateKeyGetG1Element(const PrivateKey sk, bool* didErr); +G2Element PrivateKeyGetG2Element(const PrivateKey sk, bool* didErr); +G2Element PrivateKeyGetG2Power(const PrivateKey sk, const G2Element el); +bool PrivateKeyIsEqual(const PrivateKey sk1, const PrivateKey sk2); +void* PrivateKeySerialize(const PrivateKey sk); +void PrivateKeyFree(const PrivateKey sk); +size_t PrivateKeySizeBytes(); + +#ifdef __cplusplus +} +#endif +#endif // PRIVATEKEY_H_ diff --git a/rust-bindings/bls-dash-sys/c-bindings/schemes.cpp b/rust-bindings/bls-dash-sys/c-bindings/schemes.cpp new file mode 100644 index 0000000000..bc2e632c80 --- /dev/null +++ b/rust-bindings/bls-dash-sys/c-bindings/schemes.cpp @@ -0,0 +1,388 @@ +// Copyright (c) 2021 The Dash Core developers + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 + +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "schemes.h" + +#include + +#include "bls.hpp" +#include "blschia.h" +#include "elements.h" +#include "error.h" +#include "privatekey.h" +#include "utils.hpp" + +// Implementation of bindings for CoreMPL class + +PrivateKey CoreMPLKeyGen( + const CoreMPL scheme, + const void* seed, + const size_t seedLen, + bool* didErr) +{ + bls::CoreMPL* schemePtr = (bls::CoreMPL*)scheme; + bls::PrivateKey* sk = nullptr; + try { + sk = new bls::PrivateKey( + schemePtr->KeyGen(bls::Bytes((uint8_t*)seed, seedLen))); + } catch (const std::exception& ex) { + gErrMsg = ex.what(); + *didErr = true; + return nullptr; + } + *didErr = false; + return sk; +} + +G1Element CoreMPLSkToG1(const CoreMPL scheme, const PrivateKey sk) +{ + bls::CoreMPL* schemePtr = (bls::CoreMPL*)scheme; + const bls::PrivateKey* skPtr = (bls::PrivateKey*)sk; + return new bls::G1Element(schemePtr->SkToG1(*skPtr)); +} + +G2Element CoreMPLSign( + CoreMPL scheme, + const PrivateKey sk, + const void* msg, + const size_t msgLen) +{ + bls::CoreMPL* schemePtr = (bls::CoreMPL*)scheme; + const bls::PrivateKey* skPtr = (bls::PrivateKey*)sk; + return new bls::G2Element( + schemePtr->Sign(*skPtr, bls::Bytes((uint8_t*)msg, msgLen))); +} + +bool CoreMPLVerify( + const CoreMPL scheme, + const G1Element pk, + const void* msg, + const size_t msgLen, + const G2Element sig) +{ + bls::CoreMPL* schemePtr = (bls::CoreMPL*)scheme; + const bls::G1Element* pkPtr = (bls::G1Element*)pk; + const bls::G2Element* sigPtr = (bls::G2Element*)sig; + return schemePtr->Verify( + *pkPtr, bls::Bytes((uint8_t*)msg, msgLen), *sigPtr); +} + +bool CoreMPLVerifySecure( + const CoreMPL scheme, + void** pks, + const size_t pksLen, + const G2Element sig, + const void* msg, + const size_t msgLen) +{ + bls::CoreMPL* schemePtr = (bls::CoreMPL*)scheme; + const std::vector vecPubKeys = + toBLSVector(pks, pksLen); + const uint8_t* msgPtr = (uint8_t*)msg; + const bls::G2Element* sigPtr = (bls::G2Element*)sig; + return schemePtr->VerifySecure( + vecPubKeys, *sigPtr, bls::Bytes(msgPtr, msgLen)); +} + +G1Element CoreMPLAggregatePubKeys( + const CoreMPL scheme, + void** pks, + const size_t pksLen) +{ + bls::CoreMPL* schemePtr = (bls::CoreMPL*)scheme; + return new bls::G1Element( + schemePtr->Aggregate(toBLSVector(pks, pksLen))); +} + +G2Element CoreMPLAggregateSigs( + const CoreMPL scheme, + void** sigs, + const size_t sigsLen) +{ + bls::CoreMPL* schemePtr = (bls::CoreMPL*)scheme; + return new bls::G2Element( + schemePtr->Aggregate(toBLSVector(sigs, sigsLen))); +} + +PrivateKey CoreMPLDeriveChildSk( + const CoreMPL scheme, + const PrivateKey sk, + const uint32_t index) +{ + bls::CoreMPL* schemePtr = (bls::CoreMPL*)scheme; + const bls::PrivateKey* skPtr = (bls::PrivateKey*)sk; + return new bls::PrivateKey(schemePtr->DeriveChildSk(*skPtr, index)); +} + +PrivateKey CoreMPLDeriveChildSkUnhardened( + CoreMPL scheme, + PrivateKey sk, + uint32_t index) +{ + bls::CoreMPL* schemePtr = (bls::CoreMPL*)scheme; + bls::PrivateKey* skPtr = (bls::PrivateKey*)sk; + return new bls::PrivateKey( + schemePtr->DeriveChildSkUnhardened(*skPtr, index)); +} + +G1Element CoreMPLDeriveChildPkUnhardened( + CoreMPL scheme, + G1Element el, + uint32_t index) +{ + bls::CoreMPL* schemePtr = (bls::CoreMPL*)scheme; + bls::G1Element* elPtr = (bls::G1Element*)el; + return new bls::G1Element( + schemePtr->DeriveChildPkUnhardened(*elPtr, index)); +} + +bool CoreMPLAggregateVerify( + const CoreMPL scheme, + void** pks, + const size_t pksLen, + void** msgs, + const void* msgsLens, + const size_t msgsLen, + const G2Element sig) +{ + bls::CoreMPL* schemePtr = (bls::CoreMPL*)scheme; + const size_t* msgLensPtr = (size_t*)msgsLens; + const bls::G2Element* sigPtr = (bls::G2Element*)sig; + const std::vector vecPubKeys = + toBLSVector(pks, pksLen); + const std::vector vecMsgsLens = + std::vector(msgLensPtr, msgLensPtr + msgsLen); + const std::vector vecMsgs = + toVectorBytes(msgs, msgsLen, vecMsgsLens); + return schemePtr->AggregateVerify(vecPubKeys, vecMsgs, *sigPtr); +} + +// BasicSchemeMPL +BasicSchemeMPL NewBasicSchemeMPL() { return new bls::BasicSchemeMPL(); } + +bool BasicSchemeMPLAggregateVerify( + BasicSchemeMPL scheme, + void** pks, + const size_t pksLen, + void** msgs, + const void* msgsLens, + const size_t msgsLen, + const G2Element sig) +{ + bls::BasicSchemeMPL* schemePtr = (bls::BasicSchemeMPL*)scheme; + const size_t* msgLensPtr = (size_t*)msgsLens; + const bls::G2Element* sigPtr = (bls::G2Element*)sig; + const std::vector vecPubKeys = + toBLSVector(pks, pksLen); + const std::vector vecMsgsLens = + std::vector(msgLensPtr, msgLensPtr + msgsLen); + const std::vector vecMsgs = + toVectorBytes(msgs, msgsLen, vecMsgsLens); + return schemePtr->AggregateVerify(vecPubKeys, vecMsgs, *sigPtr); +} + +void BasicSchemeMPLFree(BasicSchemeMPL scheme) +{ + bls::BasicSchemeMPL* schemePtr = (bls::BasicSchemeMPL*)scheme; + delete schemePtr; +} + +// AugSchemeMPL +AugSchemeMPL NewAugSchemeMPL() { return new bls::AugSchemeMPL(); } + +G2Element AugSchemeMPLSign( + const AugSchemeMPL scheme, + const PrivateKey sk, + const void* msg, + const size_t msgLen) +{ + bls::AugSchemeMPL* schemePtr = (bls::AugSchemeMPL*)scheme; + const bls::PrivateKey* skPtr = (bls::PrivateKey*)sk; + return new bls::G2Element( + schemePtr->Sign(*skPtr, bls::Bytes((uint8_t*)msg, msgLen))); +} + +G2Element AugSchemeMPLSignPrepend( + const AugSchemeMPL scheme, + const PrivateKey sk, + const void* msg, + const size_t msgLen, + const G1Element prepPk) +{ + bls::AugSchemeMPL* schemePtr = (bls::AugSchemeMPL*)scheme; + const bls::PrivateKey* skPtr = (bls::PrivateKey*)sk; + const bls::G1Element* prepPkPtr = (bls::G1Element*)prepPk; + return new bls::G2Element( + schemePtr->Sign(*skPtr, bls::Bytes((uint8_t*)msg, msgLen), *prepPkPtr)); +} + +bool AugSchemeMPLVerify( + const AugSchemeMPL scheme, + const G1Element pk, + const void* msg, + const size_t msgLen, + const G2Element sig) +{ + bls::AugSchemeMPL* schemePtr = (bls::AugSchemeMPL*)scheme; + const bls::G1Element* pkPtr = (bls::G1Element*)pk; + const uint8_t* msgPtr = (uint8_t*)msg; + const bls::G2Element* sigPtr = (bls::G2Element*)sig; + return schemePtr->Verify(*pkPtr, bls::Bytes(msgPtr, msgLen), *sigPtr); +} + +bool AugSchemeMPLAggregateVerify( + const AugSchemeMPL scheme, + void** pks, + const size_t pksLen, + void** msgs, + const void* msgsLens, + const size_t msgsLen, + const G2Element sig) +{ + bls::AugSchemeMPL* schemePtr = (bls::AugSchemeMPL*)scheme; + const size_t* msgLensPtr = (size_t*)msgsLens; + const bls::G2Element* sigPtr = (bls::G2Element*)sig; + const std::vector vecPubKeys = + toBLSVector(pks, pksLen); + const std::vector vecMsgsLens = + std::vector(msgLensPtr, msgLensPtr + msgsLen); + const std::vector vecMsgs = + toVectorBytes(msgs, msgsLen, vecMsgsLens); + return schemePtr->AggregateVerify(vecPubKeys, vecMsgs, *sigPtr); +} + +void AugSchemeMPLFree(AugSchemeMPL scheme) +{ + bls::AugSchemeMPL* schemePtr = (bls::AugSchemeMPL*)scheme; + delete schemePtr; +} + +// PopSchemeMPL +PopSchemeMPL NewPopSchemeMPL() { return new bls::PopSchemeMPL(); } + +G2Element PopSchemeMPLPopProve( + const PopSchemeMPL scheme, + const PrivateKey sk) +{ + bls::PopSchemeMPL* schemePtr = (bls::PopSchemeMPL*)scheme; + const bls::PrivateKey* skPtr = (bls::PrivateKey*)sk; + return new bls::G2Element(schemePtr->PopProve(*skPtr)); +} + +bool PopSchemeMPLPopVerify( + const PopSchemeMPL scheme, + const G1Element pk, + const G2Element sig) +{ + bls::PopSchemeMPL* schemePtr = (bls::PopSchemeMPL*)scheme; + const bls::G1Element* pkPtr = (bls::G1Element*)pk; + const bls::G2Element* sigPtr = (bls::G2Element*)sig; + return schemePtr->PopVerify(*pkPtr, *sigPtr); +} + +bool PopSchemeMPLFastAggregateVerify( + const PopSchemeMPL scheme, + void** pks, + const size_t pksLen, + const void* msg, + const size_t msgLen, + const G2Element sig) +{ + bls::PopSchemeMPL* schemePtr = (bls::PopSchemeMPL*)scheme; + const bls::G2Element* sigPtr = (bls::G2Element*)sig; + const std::vector vecPubKeys = + toBLSVector(pks, pksLen); + return schemePtr->FastAggregateVerify( + vecPubKeys, bls::Bytes((uint8_t*)msg, msgLen), *sigPtr); +} + +void PopSchemeMPLFree(PopSchemeMPL scheme) +{ + bls::PopSchemeMPL* schemePtr = (bls::PopSchemeMPL*)scheme; + delete schemePtr; +} + +// LegacySchemeMPL +LegacySchemeMPL NewLegacySchemeMPL() { return new bls::LegacySchemeMPL(); } + +G2Element LegacySchemeMPLSign( + const LegacySchemeMPL scheme, + const PrivateKey sk, + const void* msg, + const size_t msgLen) +{ + bls::LegacySchemeMPL* schemePtr = (bls::LegacySchemeMPL*)scheme; + const bls::PrivateKey* skPtr = (bls::PrivateKey*)sk; + return new bls::G2Element( + schemePtr->Sign(*skPtr, bls::Bytes((uint8_t*)msg, msgLen))); +} + +bool LegacySchemeMPLVerify( + const LegacySchemeMPL scheme, + const G1Element pk, + const void* msg, + const size_t msgLen, + const G2Element sig) +{ + bls::LegacySchemeMPL* schemePtr = (bls::LegacySchemeMPL*)scheme; + const bls::G1Element* pkPtr = (bls::G1Element*)pk; + const uint8_t* msgPtr = (uint8_t*)msg; + const bls::G2Element* sigPtr = (bls::G2Element*)sig; + return schemePtr->Verify(*pkPtr, bls::Bytes(msgPtr, msgLen), *sigPtr); +} + +bool LegacySchemeMPLVerifySecure( + const LegacySchemeMPL scheme, + void** pks, + const size_t pksLen, + const G2Element sig, + const void* msg, + const size_t msgLen) +{ + bls::LegacySchemeMPL* schemePtr = (bls::LegacySchemeMPL*)scheme; + const std::vector vecPubKeys = + toBLSVector(pks, pksLen); + const uint8_t* msgPtr = (uint8_t*)msg; + const bls::G2Element* sigPtr = (bls::G2Element*)sig; + // Because of scheme pointer it will call CoreMPL::VerifySecure with 'legacy' flag variant + return schemePtr->VerifySecure( + vecPubKeys, *sigPtr, bls::Bytes(msgPtr, msgLen)); +} + +bool LegacySchemeMPLAggregateVerify( + const LegacySchemeMPL scheme, + void** pks, + const size_t pksLen, + void** msgs, + const void* msgsLens, + const size_t msgsLen, + const G2Element sig) +{ + bls::LegacySchemeMPL* schemePtr = (bls::LegacySchemeMPL*)scheme; + const size_t* msgLensPtr = (size_t*)msgsLens; + const bls::G2Element* sigPtr = (bls::G2Element*)sig; + const std::vector vecPubKeys = + toBLSVector(pks, pksLen); + const std::vector vecMsgsLens = + std::vector(msgLensPtr, msgLensPtr + msgsLen); + const std::vector vecMsgs = + toVectorBytes(msgs, msgsLen, vecMsgsLens); + return schemePtr->AggregateVerify(vecPubKeys, vecMsgs, *sigPtr); +} + +void LegacySchemeMPLFree(LegacySchemeMPL scheme) +{ + bls::LegacySchemeMPL* schemePtr = (bls::LegacySchemeMPL*)scheme; + delete schemePtr; +} diff --git a/rust-bindings/bls-dash-sys/c-bindings/schemes.h b/rust-bindings/bls-dash-sys/c-bindings/schemes.h new file mode 100644 index 0000000000..41b39a6103 --- /dev/null +++ b/rust-bindings/bls-dash-sys/c-bindings/schemes.h @@ -0,0 +1,184 @@ +// Copyright (c) 2021 The Dash Core developers + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 + +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SCHEMES_H_ +#define SCHEMES_H_ +#include +#include + +#include "elements.h" +#include "privatekey.h" +#ifdef __cplusplus +extern "C" { +#endif + +typedef void* CoreMPL; +typedef CoreMPL BasicSchemeMPL; +typedef CoreMPL AugSchemeMPL; +typedef CoreMPL PopSchemeMPL; +typedef CoreMPL LegacySchemeMPL; + +// CoreMPL +PrivateKey CoreMPLKeyGen( + const CoreMPL scheme, + const void* seed, + const size_t seedLen, + bool* didErr); +G1Element CoreMPLSkToG1(const CoreMPL scheme, const PrivateKey sk); +G2Element CoreMPLSign( + const CoreMPL scheme, + const PrivateKey sk, + const void* msg, + const size_t msgLen); +bool CoreMPLVerify( + const BasicSchemeMPL scheme, + const G1Element pk, + const void* msg, + const size_t msgLen, + const G2Element sig); +bool CoreMPLVerifySecure( + const CoreMPL scheme, + void** pks, + const size_t pksLen, + const G2Element sig, + const void* msg, + const size_t msgLen); +G1Element CoreMPLAggregatePubKeys( + const CoreMPL scheme, + void** pubKeys, + const size_t pkLen); +G2Element CoreMPLAggregateSigs( + const CoreMPL scheme, + void** sigs, + const size_t sigLen); +PrivateKey CoreMPLDeriveChildSk( + const CoreMPL scheme, + const PrivateKey sk, + const uint32_t index); +PrivateKey CoreMPLDeriveChildSkUnhardened( + const CoreMPL scheme, + const PrivateKey sk, + const uint32_t index); +G1Element CoreMPLDeriveChildPkUnhardened( + const CoreMPL scheme, + const G1Element sk, + const uint32_t index); +bool CoreMPLAggregateVerify( + const CoreMPL scheme, + void** pks, + const size_t pkLen, + void** msgs, + const void* msgLens, + const size_t msgLen, + const G2Element sig); + +// BasicSchemeMPL +BasicSchemeMPL NewBasicSchemeMPL(); +bool BasicSchemeMPLAggregateVerify( + BasicSchemeMPL scheme, + void** pks, + const size_t pksLen, + void** msgs, + const void* msgsLens, + const size_t msgsLen, + const G2Element sig); +void BasicSchemeMPLFree(BasicSchemeMPL scheme); + +// AugSchemeMPL +AugSchemeMPL NewAugSchemeMPL(); +G2Element AugSchemeMPLSign( + const AugSchemeMPL scheme, + const PrivateKey sk, + const void* msg, + const size_t msgLen); +G2Element AugSchemeMPLSignPrepend( + const AugSchemeMPL scheme, + const PrivateKey sk, + const void* msg, + const size_t msgLen, + const G1Element prepPk); +bool AugSchemeMPLVerify( + const AugSchemeMPL scheme, + const G1Element pk, + const void* msg, + const size_t msgLen, + const G2Element sig); +bool AugSchemeMPLAggregateVerify( + const AugSchemeMPL scheme, + void** pks, + const size_t pksLen, + void** msgs, + const void* msgsLens, + const size_t msgsLen, + const G2Element sig); +void AugSchemeMPLFree(AugSchemeMPL scheme); + +// PopSchemeMPL +PopSchemeMPL NewPopSchemeMPL(); +G2Element PopSchemeMPLPopProve( + const PopSchemeMPL scheme, + const PrivateKey sk); +bool PopSchemeMPLPopVerify( + const PopSchemeMPL scheme, + const G1Element pk, + const G2Element sig); +bool PopSchemeMPLFastAggregateVerify( + const PopSchemeMPL scheme, + void** pks, + const size_t pksLen, + const void* msgs, + const size_t msgsLen, + const G2Element sig); +void PopSchemeMPLFree(PopSchemeMPL scheme); + +// LegacySchemeMPL +LegacySchemeMPL NewLegacySchemeMPL(); +G2Element LegacySchemeMPLSign( + const LegacySchemeMPL scheme, + const PrivateKey sk, + const void* msg, + const size_t msgLen); +G2Element LegacySchemeMPLSignPrepend( + const LegacySchemeMPL scheme, + const PrivateKey sk, + const void* msg, + const size_t msgLen, + const G1Element prepPk); +bool LegacySchemeMPLVerify( + const LegacySchemeMPL scheme, + const G1Element pk, + const void* msg, + const size_t msgLen, + const G2Element sig); +bool LegacySchemeMPLVerifySecure( + const LegacySchemeMPL scheme, + void** pks, + const size_t pksLen, + const G2Element sig, + const void* msg, + const size_t msgLen); +bool LegacySchemeMPLAggregateVerify( + const LegacySchemeMPL scheme, + void** pks, + const size_t pksLen, + void** msgs, + const void* msgsLens, + const size_t msgsLen, + const G2Element sig); +void LegacySchemeMPLFree(LegacySchemeMPL scheme); + +#ifdef __cplusplus +} +#endif +#endif // SCHEMES_H_ diff --git a/rust-bindings/bls-dash-sys/c-bindings/threshold.cpp b/rust-bindings/bls-dash-sys/c-bindings/threshold.cpp new file mode 100644 index 0000000000..2bb668483d --- /dev/null +++ b/rust-bindings/bls-dash-sys/c-bindings/threshold.cpp @@ -0,0 +1,168 @@ +// Copyright (c) 2021 The Dash Core developers + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 + +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include +#include "bls.hpp" +#include "privatekey.h" +#include "elements.h" +#include "blschia.h" +#include "threshold.h" +#include "utils.hpp" +#include "error.h" + +std::vector toVectorHashes(void** elems, const size_t len) { + std::vector vec; + vec.reserve(len); + for (int i = 0 ; i < len; ++i) { + vec.push_back( + bls::Bytes((uint8_t*)elems[i], HashSize) + ); + } + return vec; +} + +PrivateKey ThresholdPrivateKeyShare(void** sks, const size_t sksLen, const void* hash, bool* didErr) { + bls::PrivateKey* sk = nullptr; + try { + sk = new bls::PrivateKey( + bls::Threshold::PrivateKeyShare( + toBLSVector(sks, sksLen), + bls::Bytes((uint8_t*)hash, HashSize) + ) + ); + } catch(const std::exception& ex) { + gErrMsg = ex.what(); + *didErr = true; + return nullptr; + } + *didErr = false; + return sk; +} + +PrivateKey ThresholdPrivateKeyRecover(void** sks, + const size_t sksLen, + void** hashes, + const size_t hashesLen, + bool* didErr) { + bls::PrivateKey* sk = nullptr; + std::vector pop = toVectorHashes(hashes, hashesLen); + try { + sk = new bls::PrivateKey( + bls::Threshold::PrivateKeyRecover( + toBLSVector(sks, sksLen), + toVectorHashes(hashes, hashesLen) + ) + ); + } catch(const std::exception& ex) { + gErrMsg = ex.what(); + *didErr = true; + return nullptr; + } + *didErr = false; + return sk; +} + +G1Element ThresholdPublicKeyShare(void** pks, const size_t pksLen, const void* hash, bool* didErr) { + bls::G1Element* el = nullptr; + try { + el = new bls::G1Element( + bls::Threshold::PublicKeyShare( + toBLSVector(pks, pksLen), + bls::Bytes((uint8_t*)hash, HashSize) + ) + ); + } catch(const std::exception& ex) { + gErrMsg = ex.what(); + *didErr = true; + return nullptr; + } + *didErr = false; + return el; +} + +G1Element ThresholdPublicKeyRecover(void** pks, + const size_t pksLen, + void** hashes, + const size_t hashesLen, + bool* didErr) { + bls::G1Element* el = nullptr; + try { + el = new bls::G1Element( + bls::Threshold::PublicKeyRecover( + toBLSVector(pks, pksLen), + toVectorHashes(hashes, hashesLen) + ) + ); + } catch(const std::exception& ex) { + gErrMsg = ex.what(); + *didErr = true; + return nullptr; + } + *didErr = false; + return el; +} + +G2Element ThresholdSignatureShare(void** sigs, const size_t sigsLen, const void* hash, bool* didErr) { + bls::G2Element* el = nullptr; + try { + el = new bls::G2Element( + bls::Threshold::SignatureShare( + toBLSVector(sigs, sigsLen), + bls::Bytes((uint8_t*)hash, HashSize) + ) + ); + } catch(const std::exception& ex) { + gErrMsg = ex.what(); + *didErr = true; + return nullptr; + } + *didErr = false; + return el; +} + +G2Element ThresholdSignatureRecover(void** sigs, + const size_t sigsLen, + void** hashes, + const size_t hashesLen, + bool* didErr) { + bls::G2Element* el = nullptr; + try { + el = new bls::G2Element( + bls::Threshold::SignatureRecover( + toBLSVector(sigs, sigsLen), + toVectorHashes(hashes, hashesLen) + ) + ); + } catch(const std::exception& ex) { + gErrMsg = ex.what(); + *didErr = true; + return nullptr; + } + *didErr = false; + return el; +} + +G2Element ThresholdSign(const PrivateKey sk, const void* hash) { + bls::PrivateKey* skPtr = (bls::PrivateKey*)sk; + return new bls::G2Element( + bls::Threshold::Sign(*skPtr, bls::Bytes((uint8_t*)hash, HashSize)) + ); +} + +bool ThresholdVerify(const G1Element pk, const void* hash, const G2Element sig) { + bls::G1Element* pkPtr = (bls::G1Element*)pk; + bls::G2Element* sigPtr = (bls::G2Element*)sig; + return bls::Threshold::Verify(*pkPtr, bls::Bytes((uint8_t*)hash, HashSize), *sigPtr); +} diff --git a/rust-bindings/bls-dash-sys/c-bindings/threshold.h b/rust-bindings/bls-dash-sys/c-bindings/threshold.h new file mode 100644 index 0000000000..054ddffcd8 --- /dev/null +++ b/rust-bindings/bls-dash-sys/c-bindings/threshold.h @@ -0,0 +1,55 @@ +// Copyright (c) 2021 The Dash Core developers + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 + +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef THRESHOLD_H_ +#define THRESHOLD_H_ +#include +#include +#include +#include "privatekey.h" +#include "elements.h" +#ifdef __cplusplus +extern "C" { +#endif + +const int HashSize = 32; + +PrivateKey ThresholdPrivateKeyShare(void** sks, const size_t sksLen, const void* hash, bool* didErr); +PrivateKey ThresholdPrivateKeyRecover(void** sks, + const size_t sksLen, + void** hashes, + const size_t hashesLen, + bool* didErr); + +G1Element ThresholdPublicKeyShare(void** pks, const size_t pksLen, const void* hash, bool* didErr); +G1Element ThresholdPublicKeyRecover(void** pks, + const size_t pksLen, + void** hashes, + const size_t hashesLen, + bool* didErr); + +G2Element ThresholdSignatureShare(void** sigs, const size_t sigsLen, const void* hash, bool* didErr); +G2Element ThresholdSignatureRecover(void** sigs, + const size_t sigsLen, + void** hashes, + const size_t hashesLen, + bool* didErr); + +G2Element ThresholdSign(const PrivateKey sk, const void* hash); +bool ThresholdVerify(const G1Element pk, const void* hash, const G2Element sig); + +#ifdef __cplusplus +} +#endif +#endif // THRESHOLD_H_ diff --git a/rust-bindings/bls-dash-sys/c-bindings/utils.cpp b/rust-bindings/bls-dash-sys/c-bindings/utils.cpp new file mode 100644 index 0000000000..85ad174c84 --- /dev/null +++ b/rust-bindings/bls-dash-sys/c-bindings/utils.cpp @@ -0,0 +1,40 @@ +// Copyright (c) 2021 The Dash Core developers + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 + +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include "bls.hpp" +#include "privatekey.h" +#include "elements.h" + +// helper functions +template +std::vector toBLSVector(void** elems, const size_t len) { + std::vector vec; + vec.reserve(len); + for (int i = 0 ; i < len; ++i) { + T* el = (T*)elems[i]; + vec.push_back(*el); + } + return vec; +} + +std::vector toVectorBytes(void** elems, const size_t len, const std::vector vecElemsLens) { + std::vector vec; + vec.reserve(len); + for (int i = 0 ; i < len; ++i) { + uint8_t* elPtr = (uint8_t*)elems[i]; + vec.push_back(bls::Bytes(elPtr, vecElemsLens[i])); + } + return vec; +} diff --git a/rust-bindings/bls-dash-sys/c-bindings/utils.hpp b/rust-bindings/bls-dash-sys/c-bindings/utils.hpp new file mode 100644 index 0000000000..42e7898a3f --- /dev/null +++ b/rust-bindings/bls-dash-sys/c-bindings/utils.hpp @@ -0,0 +1,34 @@ +// Copyright (c) 2021 The Dash Core developers + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 + +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once + +#include +#include "bls.hpp" +#include "privatekey.h" +#include "elements.h" + +// helper functions +template +std::vector toBLSVector(void** elems, const size_t len) { + std::vector vec; + vec.reserve(len); + for (int i = 0 ; i < (int)len; ++i) { + const T* el = (T*)elems[i]; + vec.push_back(*el); + } + return vec; +} + +std::vector toVectorBytes(void** elems, const size_t len, const std::vector vecElemsLens); diff --git a/rust-bindings/bls-dash-sys/include.h b/rust-bindings/bls-dash-sys/include.h new file mode 100644 index 0000000000..4189a0748c --- /dev/null +++ b/rust-bindings/bls-dash-sys/include.h @@ -0,0 +1,8 @@ +#include "c-bindings/blschia.h" +#include "c-bindings/elements.h" +#include "c-bindings/privatekey.h" +#include "c-bindings/schemes.h" +#include "c-bindings/threshold.h" +#include "c-bindings/bip32/chaincode.h" +#include "c-bindings/bip32/extendedprivatekey.h" +#include "c-bindings/bip32/extendedpublickey.h" diff --git a/rust-bindings/bls-dash-sys/src/lib.rs b/rust-bindings/bls-dash-sys/src/lib.rs new file mode 100644 index 0000000000..a24bad5d77 --- /dev/null +++ b/rust-bindings/bls-dash-sys/src/lib.rs @@ -0,0 +1,6 @@ +#![allow(non_upper_case_globals)] +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] + +// include!(concat!(env!("OUT_DIR"), "/bindings.rs")); +include!("../bindings.rs"); diff --git a/rust-bindings/bls-dash-sys/tests/sign_and_verify.rs b/rust-bindings/bls-dash-sys/tests/sign_and_verify.rs new file mode 100644 index 0000000000..6ceee4961c --- /dev/null +++ b/rust-bindings/bls-dash-sys/tests/sign_and_verify.rs @@ -0,0 +1,79 @@ +use bls_dash_sys as sys; + +#[test] +fn sign_and_verify() { + let seed = b"seedweedseedweedseedweedseedweed"; + let bad_seed = b"weedseedweedseedweedseedweedseed"; + + unsafe { + let scheme = sys::NewAugSchemeMPL(); + let mut did_err = false; + + let sk = sys::CoreMPLKeyGen( + scheme, + seed.as_ptr() as *const _, + seed.len(), + &mut did_err as *mut _, + ); + assert!(!did_err); + + let pk = sys::PrivateKeyGetG1Element(sk, &mut did_err as *mut _); + assert!(!did_err); + + let sk2 = sys::CoreMPLKeyGen( + scheme, + bad_seed.as_ptr() as *const _, + bad_seed.len(), + &mut did_err as *mut _, + ); + assert!(!did_err); + + let pk2 = sys::PrivateKeyGetG1Element(sk2, &mut did_err as *mut _); + assert!(!did_err); + + let message = b"Evgeny owns 1337 dash no cap"; + let sig = sys::CoreMPLSign(scheme, sk, message.as_ptr() as *const _, message.len()); + + let verify = + sys::CoreMPLVerify(scheme, pk, message.as_ptr() as *const _, message.len(), sig); + assert!(verify); + + let verify_bad = sys::CoreMPLVerify( + scheme, + pk2, + message.as_ptr() as *const _, + message.len(), + sig, + ); + assert!(!verify_bad); + + sys::G2ElementFree(sig); + sys::G1ElementFree(pk2); + sys::PrivateKeyFree(sk2); + sys::G1ElementFree(pk); + sys::PrivateKeyFree(sk); + sys::AugSchemeMPLFree(scheme); + } +} + +#[test] +fn test_private_key_from_bip32() { + use std::slice; + let long_seed: [u8; 32] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2]; + let long_private_key_test_data: [u8; 32] = [50, 67, 148, 112, 207, 6, 210, 118, 137, 125, 27, 144, 105, 189, 214, 228, 68, 83, 144, 205, 80, 105, 133, 222, 14, 26, 28, 136, 167, 111, 241, 118]; + let short_seed: [u8; 10] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + let short_private_key_test_data: [u8; 32] = [70, 137, 28, 44, 236, 73, 89, 60, 129, 146, 30, 71, 61, 183, 72, 0, 41, 224, 252, 30, 185, 51, 198, 185, 61, 129, 245, 55, 14, 177, 159, 189]; + unsafe { + let c_private_key = sys::PrivateKeyFromSeedBIP32(long_seed.as_ptr() as *const _, long_seed.len()); + let serialized = sys::PrivateKeySerialize(c_private_key) as *const u8; + let data = slice::from_raw_parts(serialized, sys::PrivateKeySizeBytes()); + assert_eq!(data, &long_private_key_test_data); + sys::PrivateKeyFree(c_private_key); + + let c_private_key = sys::PrivateKeyFromSeedBIP32(short_seed.as_ptr() as *const _, short_seed.len()); + let serialized = sys::PrivateKeySerialize(c_private_key) as *const u8; + let data = slice::from_raw_parts(serialized, sys::PrivateKeySizeBytes()); + assert_eq!(data, &short_private_key_test_data); + sys::PrivateKeyFree(c_private_key); + } +} diff --git a/rust-bindings/bls-signatures/.rustfmt.toml b/rust-bindings/bls-signatures/.rustfmt.toml new file mode 100644 index 0000000000..f5fe8f3188 --- /dev/null +++ b/rust-bindings/bls-signatures/.rustfmt.toml @@ -0,0 +1,17 @@ +unstable_features = true + +blank_lines_lower_bound = 0 +condense_wildcard_suffixes = true +error_on_line_overflow = true +error_on_unformatted = true +format_code_in_doc_comments = true +format_macro_matchers = true +format_strings = true +imports_granularity = "Crate" +normalize_comments = true +normalize_doc_attributes = true +reorder_impl_items = true +group_imports = "StdExternalCrate" +use_field_init_shorthand = true +use_try_shorthand = true +wrap_comments = true diff --git a/rust-bindings/bls-signatures/Cargo.toml b/rust-bindings/bls-signatures/Cargo.toml new file mode 100644 index 0000000000..8c6f1e3c1d --- /dev/null +++ b/rust-bindings/bls-signatures/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "bls-signatures" +description = "" +version = "1.2.5" +edition = "2021" + +[features] +legacy = [] +bip32 = [] +use_serde = ["serde"] +dash_helpers = ["rand"] +default = [ "legacy", "bip32", "dash_helpers", "use_serde"] +apple = ["bls-dash-sys/apple"] + +[dependencies] +bls-dash-sys = { path = "../bls-dash-sys" } +serde = { version= "1.0.160", features = ["derive"], optional = true} +rand = { version= "0.8.5", optional = true} diff --git a/rust-bindings/bls-signatures/src/bip32/chain_code.rs b/rust-bindings/bls-signatures/src/bip32/chain_code.rs new file mode 100644 index 0000000000..f5271cc45b --- /dev/null +++ b/rust-bindings/bls-signatures/src/bip32/chain_code.rs @@ -0,0 +1,33 @@ +use std::ffi::c_void; + +use bls_dash_sys::{BIP32ChainCodeFree, BIP32ChainCodeIsEqual, BIP32ChainCodeSerialize}; + +pub const BIP32_CHAIN_CODE_SIZE: usize = 32; + +#[derive(Debug)] +pub struct ChainCode { + pub(crate) c_chain_code: *mut c_void, +} + +impl ChainCode { + pub fn serialize(&self) -> Box<[u8; BIP32_CHAIN_CODE_SIZE]> { + unsafe { + let malloc_ptr = BIP32ChainCodeSerialize(self.c_chain_code); + Box::from_raw(malloc_ptr as *mut _) + } + } +} + +impl PartialEq for ChainCode { + fn eq(&self, other: &Self) -> bool { + unsafe { BIP32ChainCodeIsEqual(self.c_chain_code, other.c_chain_code) } + } +} + +impl Eq for ChainCode {} + +impl Drop for ChainCode { + fn drop(&mut self) { + unsafe { BIP32ChainCodeFree(self.c_chain_code) } + } +} diff --git a/rust-bindings/bls-signatures/src/bip32/mod.rs b/rust-bindings/bls-signatures/src/bip32/mod.rs new file mode 100644 index 0000000000..6b3a64326e --- /dev/null +++ b/rust-bindings/bls-signatures/src/bip32/mod.rs @@ -0,0 +1,7 @@ +mod chain_code; +mod private_key; +mod public_key; + +pub use chain_code::*; +pub use private_key::*; +pub use public_key::*; diff --git a/rust-bindings/bls-signatures/src/bip32/private_key.rs b/rust-bindings/bls-signatures/src/bip32/private_key.rs new file mode 100644 index 0000000000..af4394f179 --- /dev/null +++ b/rust-bindings/bls-signatures/src/bip32/private_key.rs @@ -0,0 +1,205 @@ +use std::ffi::c_void; + +use bls_dash_sys::{ + BIP32ExtendedPrivateKeyFree, BIP32ExtendedPrivateKeyFromBytes, BIP32ExtendedPrivateKeyFromSeed, + BIP32ExtendedPrivateKeyGetChainCode, BIP32ExtendedPrivateKeyGetExtendedPublicKey, + BIP32ExtendedPrivateKeyGetPrivateKey, BIP32ExtendedPrivateKeyGetPublicKey, + BIP32ExtendedPrivateKeyIsEqual, BIP32ExtendedPrivateKeyPrivateChild, + BIP32ExtendedPrivateKeyPublicChild, BIP32ExtendedPrivateKeySerialize, +}; + +use crate::{ + bip32::{chain_code::ChainCode, ExtendedPublicKey}, + utils::{c_err_to_result, SecureBox}, + BlsError, G1Element, PrivateKey, +}; + +pub const BIP32_EXTENDED_PRIVATE_KEY_SIZE: usize = 77; + +#[derive(Debug)] +pub struct ExtendedPrivateKey { + c_extended_private_key: *mut c_void, +} + +impl PartialEq for ExtendedPrivateKey { + fn eq(&self, other: &Self) -> bool { + unsafe { + BIP32ExtendedPrivateKeyIsEqual( + self.c_extended_private_key, + other.c_extended_private_key, + ) + } + } +} + +impl Eq for ExtendedPrivateKey {} + +impl ExtendedPrivateKey { + pub fn from_bytes(bytes: &[u8]) -> Result { + if bytes.len() != BIP32_EXTENDED_PRIVATE_KEY_SIZE { + return Err(BlsError { + msg: format!( + "Extended Private Key size must be {}, got {}", + BIP32_EXTENDED_PRIVATE_KEY_SIZE, + bytes.len() + ), + }); + } + Ok(ExtendedPrivateKey { + c_extended_private_key: c_err_to_result(|did_err| unsafe { + BIP32ExtendedPrivateKeyFromBytes(bytes.as_ptr() as *const _, did_err) + })?, + }) + } + + pub fn from_seed(bytes: &[u8]) -> Result { + Ok(ExtendedPrivateKey { + c_extended_private_key: c_err_to_result(|did_err| unsafe { + BIP32ExtendedPrivateKeyFromSeed(bytes.as_ptr() as *const _, bytes.len(), did_err) + })?, + }) + } + + pub(crate) fn private_child_with_legacy_flag(&self, index: u32, legacy: bool) -> Self { + ExtendedPrivateKey { + c_extended_private_key: unsafe { + BIP32ExtendedPrivateKeyPrivateChild(self.c_extended_private_key, index, legacy) + }, + } + } + + pub fn private_child(&self, index: u32) -> Self { + self.private_child_with_legacy_flag(index, false) + } + + pub fn public_child(&self, index: u32) -> ExtendedPublicKey { + ExtendedPublicKey { + c_extended_public_key: unsafe { + BIP32ExtendedPrivateKeyPublicChild(self.c_extended_private_key, index) + }, + } + } + + pub(crate) fn extended_public_key_with_legacy_flag( + &self, + legacy: bool, + ) -> Result { + Ok(ExtendedPublicKey { + c_extended_public_key: c_err_to_result(|did_err| unsafe { + BIP32ExtendedPrivateKeyGetExtendedPublicKey( + self.c_extended_private_key, + legacy, + did_err, + ) + })?, + }) + } + + pub fn extended_public_key(&self) -> Result { + self.extended_public_key_with_legacy_flag(false) + } + + pub fn public_key(&self) -> Result { + Ok(G1Element { + c_element: c_err_to_result(|did_err| unsafe { + BIP32ExtendedPrivateKeyGetPublicKey(self.c_extended_private_key, did_err) + })?, + }) + } + + pub fn private_key(&self) -> PrivateKey { + PrivateKey { + c_private_key: unsafe { + BIP32ExtendedPrivateKeyGetPrivateKey(self.c_extended_private_key) + }, + } + } + + pub fn serialize(&self) -> SecureBox { + unsafe { + let secalloc_ptr = BIP32ExtendedPrivateKeySerialize(self.c_extended_private_key); + SecureBox::from_ptr(secalloc_ptr as *mut u8, BIP32_EXTENDED_PRIVATE_KEY_SIZE) + } + } + + pub fn chain_code(&self) -> ChainCode { + ChainCode { + c_chain_code: unsafe { + BIP32ExtendedPrivateKeyGetChainCode(self.c_extended_private_key) + }, + } + } +} + +impl Drop for ExtendedPrivateKey { + fn drop(&mut self) { + unsafe { BIP32ExtendedPrivateKeyFree(self.c_extended_private_key) } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn serialize_deserialize() { + let seed = b"seedweedseedweedseedweedseedweed"; + let private_key = + ExtendedPrivateKey::from_seed(seed).expect("cannot generate extended private key"); + + let private_key_bytes = private_key.serialize(); + let private_key_2 = ExtendedPrivateKey::from_bytes(private_key_bytes.as_ref()) + .expect("cannot deserialize extended private key"); + + assert_eq!(private_key, private_key_2); + assert_eq!(private_key.private_key(), private_key_2.private_key()); + assert_eq!(private_key.public_key(), private_key_2.public_key()); + } + + #[test] + fn hierarchical_deterministic_keys() { + let seed = b"seedweedseedweedseedweedseedweed"; + let private_key = + ExtendedPrivateKey::from_seed(seed).expect("cannot generate extended private key"); + let public_key = private_key + .extended_public_key() + .expect("cannot get extended public key"); + + let private_child = private_key.private_child(1337); + let private_grandchild = private_child.private_child(420); + + let public_child = public_key.public_child(1337); + let public_grandchild = public_child.public_child(420); + + assert_eq!( + public_grandchild, + private_grandchild + .extended_public_key() + .expect("cannot get extended public key") + ); + } + + #[test] + fn public_keys_match() { + let seed = b"seedweedseedweedseedweedseedweed"; + let private_key = + ExtendedPrivateKey::from_seed(seed).expect("cannot generate extended private key"); + let public_key = private_key + .extended_public_key() + .expect("cannot get extended public key"); + + assert_eq!(private_key.public_key(), Ok(public_key.public_key())); + } + + #[test] + fn fingerprint_for_short_bip32_seed() { + assert_eq!( + ExtendedPrivateKey::from_seed(&[1u8, 50, 6, 244, 24, 199, 1, 25]) + .expect("cannot generate extended private key") + .public_key() + .expect("cannot get public key from extended private key") + .fingerprint_legacy(), + 0xa4700b27 + ); + } +} diff --git a/rust-bindings/bls-signatures/src/bip32/public_key.rs b/rust-bindings/bls-signatures/src/bip32/public_key.rs new file mode 100644 index 0000000000..43fa484f0c --- /dev/null +++ b/rust-bindings/bls-signatures/src/bip32/public_key.rs @@ -0,0 +1,119 @@ +use std::ffi::c_void; + +use bls_dash_sys::{ + BIP32ExtendedPublicKeyFree, BIP32ExtendedPublicKeyFromBytes, + BIP32ExtendedPublicKeyGetChainCode, BIP32ExtendedPublicKeyGetPublicKey, + BIP32ExtendedPublicKeyIsEqual, BIP32ExtendedPublicKeyPublicChild, + BIP32ExtendedPublicKeySerialize, +}; + +use crate::{bip32::chain_code::ChainCode, utils::c_err_to_result, BlsError, G1Element}; + +pub const BIP32_EXTENDED_PUBLIC_KEY_SIZE: usize = 93; + +#[derive(Debug)] +pub struct ExtendedPublicKey { + pub(crate) c_extended_public_key: *mut c_void, +} + +impl PartialEq for ExtendedPublicKey { + fn eq(&self, other: &Self) -> bool { + unsafe { + BIP32ExtendedPublicKeyIsEqual(self.c_extended_public_key, other.c_extended_public_key) + } + } +} + +impl Eq for ExtendedPublicKey {} + +impl ExtendedPublicKey { + pub(crate) fn from_bytes_with_legacy_flag( + bytes: &[u8], + legacy: bool, + ) -> Result { + if bytes.len() != BIP32_EXTENDED_PUBLIC_KEY_SIZE { + return Err(BlsError { + msg: format!( + "Extended Public Key size must be {}, got {}", + BIP32_EXTENDED_PUBLIC_KEY_SIZE, + bytes.len() + ), + }); + } + Ok(ExtendedPublicKey { + c_extended_public_key: c_err_to_result(|did_err| unsafe { + BIP32ExtendedPublicKeyFromBytes(bytes.as_ptr() as *const _, legacy, did_err) + })?, + }) + } + + pub fn from_bytes(bytes: &[u8]) -> Result { + Self::from_bytes_with_legacy_flag(bytes, false) + } + + pub(crate) fn public_child_with_legacy_flag(&self, index: u32, legacy: bool) -> Self { + ExtendedPublicKey { + c_extended_public_key: unsafe { + BIP32ExtendedPublicKeyPublicChild(self.c_extended_public_key, index, legacy) + }, + } + } + + pub fn public_child(&self, index: u32) -> Self { + self.public_child_with_legacy_flag(index, false) + } + + pub(crate) fn serialize_with_legacy_flag( + &self, + legacy: bool, + ) -> Box<[u8; BIP32_EXTENDED_PUBLIC_KEY_SIZE]> { + unsafe { + let malloc_ptr = BIP32ExtendedPublicKeySerialize(self.c_extended_public_key, legacy); + Box::from_raw(malloc_ptr as *mut _) + } + } + + pub fn serialize(&self) -> Box<[u8; BIP32_EXTENDED_PUBLIC_KEY_SIZE]> { + self.serialize_with_legacy_flag(false) + } + + pub fn chain_code(&self) -> ChainCode { + ChainCode { + c_chain_code: unsafe { BIP32ExtendedPublicKeyGetChainCode(self.c_extended_public_key) }, + } + } + + pub fn public_key(&self) -> G1Element { + G1Element { + c_element: unsafe { BIP32ExtendedPublicKeyGetPublicKey(self.c_extended_public_key) }, + } + } +} + +impl Drop for ExtendedPublicKey { + fn drop(&mut self) { + unsafe { BIP32ExtendedPublicKeyFree(self.c_extended_public_key) } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::bip32::ExtendedPrivateKey; + + #[test] + fn serialize_deserialize() { + let seed = b"seedweedseedweedseedweedseedweed"; + let private_key = + ExtendedPrivateKey::from_seed(seed).expect("cannot generate extended private key"); + let public_key = private_key + .extended_public_key() + .expect("cannot get extended public key"); + + let public_key_bytes = public_key.serialize(); + let public_key_2 = ExtendedPublicKey::from_bytes(public_key_bytes.as_ref()) + .expect("cannot deserialize extended public key"); + + assert_eq!(public_key, public_key_2); + } +} diff --git a/rust-bindings/bls-signatures/src/elements.rs b/rust-bindings/bls-signatures/src/elements.rs new file mode 100644 index 0000000000..3388ce022a --- /dev/null +++ b/rust-bindings/bls-signatures/src/elements.rs @@ -0,0 +1,368 @@ +use std::ffi::c_void; + +use bls_dash_sys::{CoreMPLDeriveChildPkUnhardened, G1ElementFree, G1ElementFromBytes, G1ElementGenerator, G1ElementGetFingerprint, G1ElementIsEqual, G1ElementSerialize, G1ElementCopy, G2ElementCopy, G2ElementFree, G2ElementFromBytes, G2ElementIsEqual, G2ElementSerialize, ThresholdPublicKeyRecover, ThresholdSignatureRecover}; +#[cfg(feature = "use_serde")] +use serde::{Deserialize, Deserializer, Serialize, Serializer}; + +use crate::{schemes::Scheme, utils::c_err_to_result, BlsError, BasicSchemeMPL}; + +// TODO Split into modules + +pub const G1_ELEMENT_SIZE: usize = 48; // TODO somehow extract it from bls library +pub const G2_ELEMENT_SIZE: usize = 96; // TODO somehow extract it from bls library + +#[cfg(feature = "dash_helpers")] +pub type PublicKey = G1Element; + +#[cfg(feature = "dash_helpers")] +pub type Signature = G2Element; + +#[derive(Debug)] +pub struct G1Element { + pub(crate) c_element: *mut c_void, +} + +impl PartialEq for G1Element { + fn eq(&self, other: &Self) -> bool { + unsafe { G1ElementIsEqual(self.c_element, other.c_element) } + } +} + +impl Eq for G1Element {} + +impl G1Element { + pub fn generate() -> Self { + let c_element = unsafe { G1ElementGenerator() }; + + G1Element { c_element } + } + + #[cfg(feature = "dash_helpers")] + pub fn verify(&self, signature: &G2Element, message: &[u8]) -> bool { + self.verify_basic(signature, message) + } + + pub fn verify_basic(&self, signature: &G2Element, message: &[u8]) -> bool { + let basic_scheme = BasicSchemeMPL::new(); + basic_scheme.verify(self, message, signature) + } + + pub(crate) fn from_bytes_with_legacy_flag( + bytes: &[u8], + legacy: bool, + ) -> Result { + if bytes.len() != G1_ELEMENT_SIZE { + return Err(BlsError { + msg: format!( + "G1 Element size must be {}, got {}", + G1_ELEMENT_SIZE, + bytes.len() + ), + }); + } + Ok(G1Element { + c_element: c_err_to_result(|did_err| unsafe { + G1ElementFromBytes(bytes.as_ptr() as *const _, legacy, did_err) + })?, + }) + } + + pub fn from_bytes(bytes: &[u8]) -> Result { + Self::from_bytes_with_legacy_flag(bytes, false) + } + + pub(crate) fn to_bytes_with_legacy_flag(&self, legacy: bool) -> Box<[u8; G1_ELEMENT_SIZE]> { + unsafe { + let malloc_ptr = G1ElementSerialize(self.c_element, legacy); + Box::from_raw(malloc_ptr as *mut _) + } + } + + pub fn to_bytes(&self) -> Box<[u8; G1_ELEMENT_SIZE]> { + self.to_bytes_with_legacy_flag(false) + } + + pub fn derive_child_public_key_unhardened( + &self, + scheme: &impl Scheme, + index: u32, + ) -> G1Element { + G1Element { + c_element: unsafe { + CoreMPLDeriveChildPkUnhardened(scheme.as_mut_ptr(), self.c_element, index) + }, + } + } + + pub(crate) fn fingerprint_with_legacy_flag(&self, legacy: bool) -> u32 { + unsafe { G1ElementGetFingerprint(self.c_element, legacy) } + } + + pub fn fingerprint(&self) -> u32 { + self.fingerprint_with_legacy_flag(false) + } + + pub fn threshold_recover( + bls_ids_with_elements: &[(Vec, G1Element)], + ) -> Result { + unsafe { + let len = bls_ids_with_elements.len(); + let (c_hashes, c_elements): (Vec<_>, Vec<_>) = bls_ids_with_elements + .iter() + .map(|(hash, element)| { + ( + hash.as_ptr() as *mut c_void, + element.c_element as *mut c_void, + ) + }) + .unzip(); + let c_hashes_ptr = c_hashes.as_ptr() as *mut *mut c_void; + let c_elements_ptr = c_elements.as_ptr() as *mut *mut c_void; + Ok(G1Element { + c_element: c_err_to_result(|did_err| { + ThresholdPublicKeyRecover(c_elements_ptr, len, c_hashes_ptr, len, did_err) + })?, + }) + } + } +} + +impl Clone for G1Element { + fn clone(&self) -> Self { + unsafe { + G1Element{c_element: G1ElementCopy(self.c_element)} + } + } +} + +#[cfg(feature = "use_serde")] +// Implement Serialize trait for G1Element +impl Serialize for G1Element { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + let bytes = *self.to_bytes(); + serializer.serialize_bytes(&bytes) + } +} + +#[cfg(feature = "use_serde")] +// Implement Deserialize trait for G1Element +impl<'de> Deserialize<'de> for G1Element { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct G1ElementVisitor; + + impl<'de> serde::de::Visitor<'de> for G1ElementVisitor { + type Value = G1Element; + + fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + formatter.write_str("a byte array representing a G1Element") + } + + fn visit_bytes(self, bytes: &[u8]) -> Result + where + E: serde::de::Error, + { + G1Element::from_bytes(bytes).map_err(serde::de::Error::custom) + } + } + + deserializer.deserialize_bytes(G1ElementVisitor) + } +} + +impl Drop for G1Element { + fn drop(&mut self) { + unsafe { G1ElementFree(self.c_element) } + } +} + +#[derive(Debug)] +pub struct G2Element { + pub(crate) c_element: *mut c_void, +} + +impl PartialEq for G2Element { + fn eq(&self, other: &Self) -> bool { + unsafe { G2ElementIsEqual(self.c_element, other.c_element) } + } +} + +impl Eq for G2Element {} + +impl G2Element { + pub(crate) fn from_bytes_with_legacy_flag( + bytes: &[u8], + legacy: bool, + ) -> Result { + if bytes.len() != G2_ELEMENT_SIZE { + return Err(BlsError { + msg: format!( + "G2 Element size must be {}, got {}", + G2_ELEMENT_SIZE, + bytes.len() + ), + }); + } + Ok(G2Element { + c_element: c_err_to_result(|did_err| unsafe { + G2ElementFromBytes(bytes.as_ptr() as *const _, legacy, did_err) + })?, + }) + } + + pub fn from_bytes(bytes: &[u8]) -> Result { + Self::from_bytes_with_legacy_flag(bytes, false) + } + + pub(crate) fn to_bytes_with_legacy_flag(&self, legacy: bool) -> Box<[u8; G2_ELEMENT_SIZE]> { + unsafe { + let malloc_ptr = G2ElementSerialize(self.c_element, legacy); + Box::from_raw(malloc_ptr as *mut _) + } + } + + pub fn to_bytes(&self) -> Box<[u8; G2_ELEMENT_SIZE]> { + self.to_bytes_with_legacy_flag(false) + } + + pub fn threshold_recover( + bls_ids_with_elements: &[(Vec, G2Element)], + ) -> Result { + unsafe { + let len = bls_ids_with_elements.len(); + let (c_hashes, c_elements): (Vec<_>, Vec<_>) = bls_ids_with_elements + .iter() + .map(|(hash, element)| { + ( + hash.as_ptr() as *mut c_void, + element.c_element as *mut c_void, + ) + }) + .unzip(); + let c_hashes_ptr = c_hashes.as_ptr() as *mut *mut c_void; + let c_elements_ptr = c_elements.as_ptr() as *mut *mut c_void; + Ok(G2Element { + c_element: c_err_to_result(|did_err| { + ThresholdSignatureRecover(c_elements_ptr, len, c_hashes_ptr, len, did_err) + })?, + }) + } + } +} + +impl Clone for G2Element { + fn clone(&self) -> Self { + unsafe { + G2Element{c_element: G2ElementCopy(self.c_element)} + } + } +} + +#[cfg(feature = "use_serde")] +// Implement Serialize trait for G1Element +impl Serialize for G2Element { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + let bytes = *self.to_bytes(); + serializer.serialize_bytes(&bytes) + } +} + +#[cfg(feature = "use_serde")] +// Implement Deserialize trait for G1Element +impl<'de> Deserialize<'de> for G2Element { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct G2ElementVisitor; + + impl<'de> serde::de::Visitor<'de> for G2ElementVisitor { + type Value = G2Element; + + fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + formatter.write_str("a byte array representing a G2Element") + } + + fn visit_bytes(self, bytes: &[u8]) -> Result + where + E: serde::de::Error, + { + G2Element::from_bytes(bytes).map_err(serde::de::Error::custom) + } + } + + deserializer.deserialize_bytes(G2ElementVisitor) + } +} + +impl Drop for G2Element { + fn drop(&mut self) { + unsafe { G2ElementFree(self.c_element) } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::{ + schemes::{AugSchemeMPL, Scheme}, + PrivateKey, + }; + + #[test] + fn g1_serialize_deserialize() { + let seed = b"seedweedseedweedseedweedseedweed"; + let scheme = AugSchemeMPL::new(); + let sk = PrivateKey::key_gen(&scheme, seed).expect("unable to generate private key"); + + let g1 = sk.g1_element().expect("cannot get G1 element"); + let g1_bytes = g1.to_bytes(); + let g1_2 = + G1Element::from_bytes(g1_bytes.as_ref()).expect("cannot build G1 element from bytes"); + + assert_eq!(g1, g1_2); + } + + #[test] + fn g2_serialize_deserialize() { + let seed = b"seedweedseedweedseedweedseedweed"; + let scheme = AugSchemeMPL::new(); + let sk = PrivateKey::key_gen(&scheme, seed).expect("unable to generate private key"); + + let g2 = scheme.sign(&sk, b"ayy"); + let g2_bytes = g2.to_bytes(); + let g2_2 = + G2Element::from_bytes(g2_bytes.as_ref()).expect("cannot build G2 element from bytes"); + + assert_eq!(g2, g2_2); + } + + #[test] + fn should_generate_new_g1_element() { + let g1_element = G1Element::generate(); + + assert_eq!(g1_element.to_bytes().len(), 48); + } + + #[test] + fn should_return_fingerprint() { + let bytes = [ + 151, 241, 211, 167, 49, 151, 215, 148, 38, 149, 99, 140, 79, 169, 172, 15, 195, 104, + 140, 79, 151, 116, 185, 5, 161, 78, 58, 63, 23, 27, 172, 88, 108, 85, 232, 63, 249, + 122, 26, 239, 251, 58, 240, 10, 219, 34, 198, 187, + ]; + + let g1_element = + G1Element::from_bytes(&bytes).expect("should create g1 element from bytes"); + + assert_eq!(g1_element.fingerprint(), 2093959050); + } +} diff --git a/rust-bindings/bls-signatures/src/legacy/bip32/mod.rs b/rust-bindings/bls-signatures/src/legacy/bip32/mod.rs new file mode 100644 index 0000000000..5426eac84a --- /dev/null +++ b/rust-bindings/bls-signatures/src/legacy/bip32/mod.rs @@ -0,0 +1,2 @@ +mod private_key; +mod public_key; diff --git a/rust-bindings/bls-signatures/src/legacy/bip32/private_key.rs b/rust-bindings/bls-signatures/src/legacy/bip32/private_key.rs new file mode 100644 index 0000000000..c818c37214 --- /dev/null +++ b/rust-bindings/bls-signatures/src/legacy/bip32/private_key.rs @@ -0,0 +1,58 @@ +use crate::{ + bip32::{ExtendedPrivateKey, ExtendedPublicKey}, + BlsError, +}; + +impl ExtendedPrivateKey { + pub fn private_child_legacy(&self, index: u32) -> Self { + self.private_child_with_legacy_flag(index, true) + } + + pub fn extended_public_key_legacy(&self) -> Result { + self.extended_public_key_with_legacy_flag(true) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn serialize_deserialize_legacy() { + let seed = b"seedweedseedweedseedweedseedweed"; + let private_key = + ExtendedPrivateKey::from_seed(seed).expect("cannot generate extended private key"); + let public_key = private_key + .extended_public_key_legacy() + .expect("cannot get extended public key"); + + let public_key_bytes = public_key.serialize_legacy(); + let public_key_2 = ExtendedPublicKey::from_bytes_legacy(public_key_bytes.as_ref()) + .expect("cannot deserialize extended public key"); + + assert_eq!(public_key, public_key_2); + } + + #[test] + fn hierarchical_deterministic_keys_legacy() { + let seed = b"seedweedseedweedseedweedseedweed"; + let private_key = + ExtendedPrivateKey::from_seed(seed).expect("cannot generate extended private key"); + let public_key = private_key + .extended_public_key_legacy() + .expect("cannot get extended public key"); + + let private_child = private_key.private_child_legacy(1337); + let private_grandchild = private_child.private_child_legacy(420); + + let public_child = public_key.public_child_legacy(1337); + let public_grandchild = public_child.public_child_legacy(420); + + assert_eq!( + public_grandchild, + private_grandchild + .extended_public_key_legacy() + .expect("cannot get extended public key") + ); + } +} diff --git a/rust-bindings/bls-signatures/src/legacy/bip32/public_key.rs b/rust-bindings/bls-signatures/src/legacy/bip32/public_key.rs new file mode 100644 index 0000000000..eb0bda8513 --- /dev/null +++ b/rust-bindings/bls-signatures/src/legacy/bip32/public_key.rs @@ -0,0 +1,40 @@ +use crate::{ + bip32::{ExtendedPublicKey, BIP32_EXTENDED_PUBLIC_KEY_SIZE}, + BlsError, +}; + +impl ExtendedPublicKey { + pub fn from_bytes_legacy(bytes: &[u8]) -> Result { + Self::from_bytes_with_legacy_flag(bytes, true) + } + + pub fn public_child_legacy(&self, index: u32) -> Self { + self.public_child_with_legacy_flag(index, true) + } + + pub fn serialize_legacy(&self) -> Box<[u8; BIP32_EXTENDED_PUBLIC_KEY_SIZE]> { + self.serialize_with_legacy_flag(true) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::bip32::ExtendedPrivateKey; + + #[test] + fn serialize_deserialize_legacy() { + let seed = b"seedweedseedweedseedweedseedweed"; + let private_key = + ExtendedPrivateKey::from_seed(seed).expect("cannot generate extended private key"); + let public_key = private_key + .extended_public_key_legacy() + .expect("cannot get extended public key"); + + let public_key_bytes = public_key.serialize_legacy(); + let public_key_2 = ExtendedPublicKey::from_bytes_legacy(public_key_bytes.as_ref()) + .expect("cannot deserialize extended public key"); + + assert_eq!(public_key, public_key_2); + } +} diff --git a/rust-bindings/bls-signatures/src/legacy/elements.rs b/rust-bindings/bls-signatures/src/legacy/elements.rs new file mode 100644 index 0000000000..ca205a8073 --- /dev/null +++ b/rust-bindings/bls-signatures/src/legacy/elements.rs @@ -0,0 +1,25 @@ +use crate::{BlsError, G1Element, G2Element, G1_ELEMENT_SIZE, G2_ELEMENT_SIZE}; + +impl G1Element { + pub fn serialize_legacy(&self) -> Box<[u8; G1_ELEMENT_SIZE]> { + self.to_bytes_with_legacy_flag(true) + } + + pub fn from_bytes_legacy(bytes: &[u8]) -> Result { + Self::from_bytes_with_legacy_flag(bytes, true) + } + + pub fn fingerprint_legacy(&self) -> u32 { + self.fingerprint_with_legacy_flag(true) + } +} + +impl G2Element { + pub fn from_bytes_legacy(bytes: &[u8]) -> Result { + Self::from_bytes_with_legacy_flag(bytes, true) + } + + pub fn serialize_legacy(&self) -> Box<[u8; G2_ELEMENT_SIZE]> { + self.to_bytes_with_legacy_flag(true) + } +} diff --git a/rust-bindings/bls-signatures/src/legacy/mod.rs b/rust-bindings/bls-signatures/src/legacy/mod.rs new file mode 100644 index 0000000000..d84ab9d025 --- /dev/null +++ b/rust-bindings/bls-signatures/src/legacy/mod.rs @@ -0,0 +1,2 @@ +mod bip32; +mod elements; diff --git a/rust-bindings/bls-signatures/src/lib.rs b/rust-bindings/bls-signatures/src/lib.rs new file mode 100644 index 0000000000..e6d76b8149 --- /dev/null +++ b/rust-bindings/bls-signatures/src/lib.rs @@ -0,0 +1,104 @@ +mod elements; +mod private_key; +mod schemes; +mod utils; + +#[cfg(feature = "legacy")] +mod legacy; + +#[cfg(feature = "bip32")] +pub mod bip32; + +use std::{error::Error, fmt::Display}; + +pub use elements::{G1Element, G2Element, G1_ELEMENT_SIZE, G2_ELEMENT_SIZE}; +#[cfg(feature = "dash_helpers")] +pub use elements::{PublicKey, Signature}; +pub use private_key::{PrivateKey, PRIVATE_KEY_SIZE}; +pub use schemes::{AugSchemeMPL, BasicSchemeMPL, LegacySchemeMPL, Scheme}; + +#[derive(Debug, PartialEq)] +pub struct BlsError { + // Need to use owned version as each time BLS has an error its binding glue overwrites error + // message variable. + msg: String, +} + +impl Display for BlsError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.msg) + } +} + +impl Error for BlsError {} + +#[cfg(test)] +mod tests { + use super::*; + use crate::schemes::{AugSchemeMPL, Scheme}; + + #[test] + fn basic_sign() { + let seed = b"seedweedseedweedseedweedseedweed"; + let bad_seed = b"weedseedweedseedweedseedweedseed"; + + let scheme = AugSchemeMPL::new(); + + let private_key_before = + PrivateKey::key_gen(&scheme, seed).expect("unable to generate private key"); + + // Also test private key serialization + let private_key_bytes = private_key_before.to_bytes(); + let private_key = PrivateKey::from_bytes(private_key_bytes.as_slice(), false) + .expect("cannot build private key from bytes"); + drop(private_key_bytes); + + let public_key = private_key.g1_element().expect("unable to get public key"); + + let private_key_bad = + PrivateKey::key_gen(&scheme, bad_seed).expect("unable to generate private key"); + let public_key_bad = private_key_bad + .g1_element() + .expect("unable to get public key"); + + let message = b"Evgeny owns 1337 dash no cap"; + + let signature = scheme.sign(&private_key, message); + let verify = scheme.verify(&public_key, message, &signature); + assert!(verify); + let verify_bad = scheme.verify(&public_key_bad, message, &signature); + assert!(!verify_bad); + } + + #[test] + fn bad_seed() { + let seed = b"lol"; + let scheme = AugSchemeMPL::new(); + let private_key = PrivateKey::key_gen(&scheme, seed); + + assert!(matches!( + private_key, + Err(BlsError { msg }) if msg == "Seed size must be at least 32 bytes" + )); + } + + #[test] + fn hd_keys_deterministic() { + let seed = b"seedweedseedweedseedweedseedweed"; + let scheme = AugSchemeMPL::new(); + + let master_sk = PrivateKey::key_gen(&scheme, seed).expect("unable to generate private key"); + let master_pk = master_sk.g1_element().expect("unable to get public key"); + + let child_sk_u = master_sk.derive_child_private_key_unhardened(&scheme, 22); + let grandchild_sk_u = child_sk_u.derive_child_private_key_unhardened(&scheme, 0); + + let child_pk_u = master_pk.derive_child_public_key_unhardened(&scheme, 22); + let grandchild_pk_u = child_pk_u.derive_child_public_key_unhardened(&scheme, 0); + + assert_eq!( + grandchild_pk_u, + grandchild_sk_u.g1_element().expect("cannot get public key") + ); + } +} diff --git a/rust-bindings/bls-signatures/src/private_key.rs b/rust-bindings/bls-signatures/src/private_key.rs new file mode 100755 index 0000000000..bc74d710f3 --- /dev/null +++ b/rust-bindings/bls-signatures/src/private_key.rs @@ -0,0 +1,315 @@ +use std::{ffi::c_void, ops::Mul}; + +use bls_dash_sys::{ + CoreMPLDeriveChildSk, CoreMPLDeriveChildSkUnhardened, CoreMPLKeyGen, G1ElementMul, + PrivateKeyFree, PrivateKeyFromBytes, PrivateKeyFromSeedBIP32, PrivateKeyGetG1Element, + PrivateKeyIsEqual, PrivateKeySerialize, ThresholdPrivateKeyRecover, +}; +use rand::{prelude::StdRng, Rng}; +#[cfg(feature = "use_serde")] +use serde::{Deserialize, Deserializer, Serialize, Serializer}; + +use crate::{schemes::Scheme, utils::{c_err_to_result, SecureBox}, BasicSchemeMPL, BlsError, G1Element, G2Element}; + +pub const PRIVATE_KEY_SIZE: usize = 32; // TODO somehow extract it from bls library + +#[derive(Debug)] +pub struct PrivateKey { + pub(crate) c_private_key: *mut c_void, +} + +impl PartialEq for PrivateKey { + fn eq(&self, other: &Self) -> bool { + unsafe { PrivateKeyIsEqual(self.c_private_key, other.c_private_key) } + } +} + +impl Eq for PrivateKey {} + +impl Mul for PrivateKey { + type Output = Result; + + fn mul(self, rhs: G1Element) -> Self::Output { + Ok(G1Element { + c_element: c_err_to_result(|_| unsafe { + G1ElementMul(rhs.c_element, self.c_private_key) + })?, + }) + } +} + +impl Mul for G1Element { + type Output = Result; + + fn mul(self, rhs: PrivateKey) -> Self::Output { + rhs * self + } +} + +impl PrivateKey { + pub(crate) fn as_mut_ptr(&self) -> *mut c_void { + self.c_private_key + } + + // TODO Rename to from_seed + pub fn key_gen(scheme: &impl Scheme, seed: &[u8]) -> Result { + Ok(PrivateKey { + c_private_key: c_err_to_result(|did_err| unsafe { + CoreMPLKeyGen( + scheme.as_mut_ptr(), + seed.as_ptr() as *const _, + seed.len(), + did_err, + ) + })?, + }) + } + + #[cfg(feature = "dash_helpers")] + pub fn generate_dash(rng: &mut StdRng) -> Result { + let seed = rng.gen::<[u8; 32]>(); + let scheme = BasicSchemeMPL::new(); + Ok(PrivateKey { + c_private_key: c_err_to_result(|did_err| unsafe { + CoreMPLKeyGen( + scheme.as_mut_ptr(), + seed.as_ptr() as *const _, + seed.len(), + did_err, + ) + })?, + }) + } + + #[cfg(feature = "dash_helpers")] + pub fn sign(&self, message: &[u8]) -> G2Element { + self.sign_basic(message) + } + + pub fn sign_basic(&self, message: &[u8]) -> G2Element { + let scheme = BasicSchemeMPL::new(); + scheme.sign(self, message) + } + + #[cfg(feature = "dash_helpers")] + pub fn generate_dash_many(count: usize, rng: &mut StdRng) -> Result, BlsError> { + (0..count) + .into_iter() + .map(|_| Self::generate_dash(rng)) + .collect() + } + + pub fn g1_element(&self) -> Result { + Ok(G1Element { + c_element: c_err_to_result(|did_err| unsafe { + PrivateKeyGetG1Element(self.c_private_key, did_err) + })?, + }) + } + + pub fn to_bytes(&self) -> SecureBox { + // `PrivateKeySerialize` internally securely allocates memory which we have to + // wrap safely + unsafe { + SecureBox::from_ptr( + PrivateKeySerialize(self.c_private_key) as *mut u8, + PRIVATE_KEY_SIZE, + ) + } + } + + pub fn from_bytes(bytes: &[u8], mod_order: bool) -> Result { + if bytes.len() != PRIVATE_KEY_SIZE { + return Err(BlsError { + msg: format!( + "Private key size must be {}, got {}", + PRIVATE_KEY_SIZE, + bytes.len() + ), + }); + } + + let c_private_key = c_err_to_result(|did_err| unsafe { + PrivateKeyFromBytes(bytes.as_ptr() as *const c_void, mod_order, did_err) + })?; + + Ok(PrivateKey { c_private_key }) + } + + pub fn from_bip32_seed(bytes: &[u8]) -> Self { + let c_private_key = + unsafe { PrivateKeyFromSeedBIP32(bytes.as_ptr() as *const c_void, bytes.len()) }; + + PrivateKey { c_private_key } + } + + pub fn derive_child_private_key(&self, scheme: &impl Scheme, index: u32) -> PrivateKey { + PrivateKey { + c_private_key: unsafe { + CoreMPLDeriveChildSk(scheme.as_mut_ptr(), self.c_private_key, index) + }, + } + } + + pub fn derive_child_private_key_unhardened( + &self, + scheme: &impl Scheme, + index: u32, + ) -> PrivateKey { + PrivateKey { + c_private_key: unsafe { + CoreMPLDeriveChildSkUnhardened(scheme.as_mut_ptr(), self.c_private_key, index) + }, + } + } + + pub fn threshold_recover( + bls_ids_with_private_keys: &[(Vec, PrivateKey)], + ) -> Result { + unsafe { + let len = bls_ids_with_private_keys.len(); + let (c_hashes, c_elements): (Vec<_>, Vec<_>) = bls_ids_with_private_keys + .iter() + .map(|(hash, element)| (hash.as_ptr() as *mut c_void, element.c_private_key)) + .unzip(); + let c_hashes_ptr = c_hashes.as_ptr() as *mut *mut c_void; + let c_elements_ptr = c_elements.as_ptr() as *mut *mut c_void; + Ok(PrivateKey { + c_private_key: c_err_to_result(|did_err| { + ThresholdPrivateKeyRecover(c_elements_ptr, len, c_hashes_ptr, len, did_err) + })?, + }) + } + } +} + +impl Clone for PrivateKey { + fn clone(&self) -> Self { + // Serialize the element + let bytes = self.to_bytes(); + // We can panic + PrivateKey::from_bytes(bytes.as_slice(), false).expect("expected bytes to be valid") + } +} + +#[cfg(feature = "use_serde")] +// Implement Serialize trait for G1Element +impl Serialize for PrivateKey { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + serializer.serialize_bytes(self.to_bytes().as_slice()) + } +} + +#[cfg(feature = "use_serde")] +// Implement Deserialize trait for G1Element +impl<'de> Deserialize<'de> for PrivateKey { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct PrivateKeyElementVisitor; + + impl<'de> serde::de::Visitor<'de> for PrivateKeyElementVisitor { + type Value = PrivateKey; + + fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + formatter.write_str("a byte array representing a Private Key") + } + + fn visit_bytes(self, bytes: &[u8]) -> Result + where + E: serde::de::Error, + { + PrivateKey::from_bytes(bytes, false).map_err(serde::de::Error::custom) + } + } + + deserializer.deserialize_bytes(PrivateKeyElementVisitor) + } +} + +impl Drop for PrivateKey { + fn drop(&mut self) { + unsafe { PrivateKeyFree(self.c_private_key) } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::schemes::AugSchemeMPL; + + #[test] + fn serialize_deserialize() { + let seed = b"seedweedseedweedseedweedseedweed"; + let scheme = AugSchemeMPL::new(); + let sk1 = PrivateKey::key_gen(&scheme, seed).expect("unable to generate private key"); + let sk1_bytes = sk1.to_bytes(); + let sk2 = PrivateKey::from_bytes(sk1_bytes.as_slice(), false) + .expect("cannot build private key from bytes"); + + assert_eq!(sk1, sk2); + } + + #[test] + fn should_return_private_key_from_bip32_bytes() { + let long_seed = [ + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, + 9, 10, 1, 2, + ]; + let long_private_key_test_data = [ + 50, 67, 148, 112, 207, 6, 210, 118, 137, 125, 27, 144, 105, 189, 214, 228, 68, 83, 144, + 205, 80, 105, 133, 222, 14, 26, 28, 136, 167, 111, 241, 118, + ]; + let long_private_key = PrivateKey::from_bip32_seed(&long_seed); + assert_eq!(*long_private_key.to_bytes(), long_private_key_test_data); + + // Previously didn't work with seed with length != 32 + let short_seed = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + let short_private_key_test_data = [ + 70, 137, 28, 44, 236, 73, 89, 60, 129, 146, 30, 71, 61, 183, 72, 0, 41, 224, 252, 30, + 185, 51, 198, 185, 61, 129, 245, 55, 14, 177, 159, 189, + ]; + let short_private_key = PrivateKey::from_bip32_seed(&short_seed); + assert_eq!(*short_private_key.to_bytes(), short_private_key_test_data); + } + + #[test] + fn test_keys_multiplication() { + // 46891c2cec49593c81921e473db7480029e0fc1eb933c6b93d81f5370eb19fbd + let private_key_data = [ + 70, 137, 28, 44, 236, 73, 89, 60, 129, 146, 30, 71, 61, 183, 72, 0, 41, 224, 252, 30, + 185, 51, 198, 185, 61, 129, 245, 55, 14, 177, 159, 189, + ]; + // 0e2f9055c17eb13221d8b41833468ab49f7d4e874ddf4b217f5126392a608fd48ccab3510548f1da4f397c1ad4f8e01a + let public_key_data = [ + 14, 47, 144, 85, 193, 126, 177, 50, 33, 216, 180, 24, 51, 70, 138, 180, 159, 125, 78, + 135, 77, 223, 75, 33, 127, 81, 38, 57, 42, 96, 143, 212, 140, 202, 179, 81, 5, 72, 241, + 218, 79, 57, 124, 26, 212, 248, 224, 26, + ]; + // 03fd387c4d4c66ec9dcdb31ef0c08ad881090dcda13d4b2c9cbc5ef264ff4dc7 + let expected_data = [ + 3, 253, 56, 124, 77, 76, 102, 236, 157, 205, 179, 30, 240, 192, 138, 216, 129, 9, 13, + 205, 161, 61, 75, 44, 156, 188, 94, 242, 100, 255, 77, 199, + ]; + let private_key = PrivateKey::from_bytes(&private_key_data, false).unwrap(); + let public_key = G1Element::from_bytes_legacy(&public_key_data).unwrap(); + let result = (private_key * public_key).unwrap(); + assert_eq!( + &result.serialize_legacy()[..32], + &expected_data, + "should match" + ); + let private_key = PrivateKey::from_bytes(&private_key_data, false).unwrap(); + let public_key = G1Element::from_bytes_legacy(&public_key_data).unwrap(); + let result = (public_key * private_key).unwrap(); + assert_eq!( + &result.serialize_legacy()[..32], + &expected_data, + "should match" + ); + } +} diff --git a/rust-bindings/bls-signatures/src/schemes.rs b/rust-bindings/bls-signatures/src/schemes.rs new file mode 100644 index 0000000000..3019bc0b4a --- /dev/null +++ b/rust-bindings/bls-signatures/src/schemes.rs @@ -0,0 +1,434 @@ +use std::ffi::c_void; + +use bls_dash_sys::{ + AugSchemeMPLAggregateVerify, AugSchemeMPLFree, AugSchemeMPLSign, AugSchemeMPLVerify, + BasicSchemeMPLAggregateVerify, BasicSchemeMPLFree, CoreMPLAggregatePubKeys, + CoreMPLAggregateSigs, CoreMPLSign, CoreMPLVerify, CoreMPLVerifySecure, + LegacySchemeMPLAggregateVerify, LegacySchemeMPLSign, LegacySchemeMPLVerify, + LegacySchemeMPLVerifySecure, NewAugSchemeMPL, NewBasicSchemeMPL, NewLegacySchemeMPL, +}; + +// TODO Split into modules +use crate::{private_key::PrivateKey, G1Element, G2Element}; + +pub trait Scheme { + fn as_mut_ptr(&self) -> *mut c_void; + + fn sign(&self, private_key: &PrivateKey, message: &[u8]) -> G2Element; + + fn verify(&self, public_key: &G1Element, message: &[u8], signature: &G2Element) -> bool; + + fn verify_secure<'a>( + &self, + public_keys: impl IntoIterator, + message: &[u8], + signature: &G2Element, + ) -> bool { + let mut g1_pointers = public_keys + .into_iter() + .map(|g1| g1.c_element) + .collect::>(); + + unsafe { + CoreMPLVerifySecure( + self.as_mut_ptr(), + g1_pointers.as_mut_ptr(), + g1_pointers.len(), + signature.c_element, + message.as_ptr() as *const _, + message.len(), + ) + } + } + + fn aggregate_public_keys<'a>( + &self, + public_keys: impl IntoIterator, + ) -> G1Element { + let mut g1_pointers = public_keys + .into_iter() + .map(|g1| g1.c_element) + .collect::>(); + G1Element { + c_element: unsafe { + CoreMPLAggregatePubKeys( + self.as_mut_ptr(), + g1_pointers.as_mut_ptr(), + g1_pointers.len(), + ) + }, + } + } + + fn aggregate_sigs<'a>(&self, sigs: impl IntoIterator) -> G2Element { + let mut g2_pointers = sigs.into_iter().map(|g2| g2.c_element).collect::>(); + G2Element { + c_element: unsafe { + CoreMPLAggregateSigs( + self.as_mut_ptr(), + g2_pointers.as_mut_ptr(), + g2_pointers.len(), + ) + }, + } + } + + fn aggregate_verify<'a>( + &self, + public_keys: impl IntoIterator, + messages: impl IntoIterator, + signature: &G2Element, + ) -> bool; +} + +struct AggregateVerifyArgs { + g1_pointers: Vec<*mut c_void>, + messages_pointers: Vec<*const u8>, + messages_lengths: Vec, +} + +// TODO put constructor inside struct? +fn prepare_aggregate_verify_args<'a>( + public_keys: impl IntoIterator, + messages: impl IntoIterator, +) -> AggregateVerifyArgs { + let g1_pointers = public_keys + .into_iter() + .map(|g1| g1.c_element) + .collect::>(); + + let mut messages_pointers = Vec::new(); + let mut messages_lengths = Vec::new(); + + for m in messages.into_iter() { + messages_pointers.push(m.as_ptr()); + messages_lengths.push(m.len()); + } + + AggregateVerifyArgs { + g1_pointers, + messages_pointers, + messages_lengths, + } +} + +pub struct BasicSchemeMPL { + scheme: *mut c_void, +} + +impl BasicSchemeMPL { + pub fn new() -> Self { + BasicSchemeMPL { + scheme: unsafe { NewBasicSchemeMPL() }, + } + } +} + +impl Scheme for BasicSchemeMPL { + fn as_mut_ptr(&self) -> *mut c_void { + self.scheme + } + + fn sign(&self, private_key: &PrivateKey, message: &[u8]) -> G2Element { + G2Element { + c_element: unsafe { + CoreMPLSign( + self.scheme, + private_key.as_mut_ptr(), + message.as_ptr() as *const _, + message.len(), + ) + }, + } + } + + fn verify(&self, public_key: &G1Element, message: &[u8], signature: &G2Element) -> bool { + unsafe { + CoreMPLVerify( + self.scheme, + public_key.c_element, + message.as_ptr() as *const _, + message.len(), + signature.c_element, + ) + } + } + + fn aggregate_verify<'a>( + &self, + public_keys: impl IntoIterator, + messages: impl IntoIterator, + signature: &G2Element, + ) -> bool { + let AggregateVerifyArgs { + mut g1_pointers, + mut messages_pointers, + messages_lengths: mut messages_lengthes, + } = prepare_aggregate_verify_args(public_keys, messages); + + unsafe { + BasicSchemeMPLAggregateVerify( + self.as_mut_ptr(), + g1_pointers.as_mut_ptr(), + g1_pointers.len(), + messages_pointers.as_mut_ptr() as *mut _, + messages_lengthes.as_mut_ptr() as *mut _, + messages_pointers.len(), + signature.c_element, + ) + } + } +} + +pub struct LegacySchemeMPL { + scheme: *mut c_void, +} + +impl LegacySchemeMPL { + pub fn new() -> Self { + LegacySchemeMPL { + scheme: unsafe { NewLegacySchemeMPL() }, + } + } +} + +impl Scheme for LegacySchemeMPL { + fn as_mut_ptr(&self) -> *mut c_void { + self.scheme + } + + fn sign(&self, private_key: &PrivateKey, message: &[u8]) -> G2Element { + G2Element { + c_element: unsafe { + LegacySchemeMPLSign( + self.scheme, + private_key.as_mut_ptr(), + message.as_ptr() as *const _, + message.len(), + ) + }, + } + } + + fn verify(&self, public_key: &G1Element, message: &[u8], signature: &G2Element) -> bool { + unsafe { + LegacySchemeMPLVerify( + self.scheme, + public_key.c_element, + message.as_ptr() as *const _, + message.len(), + signature.c_element, + ) + } + } + + fn verify_secure<'a>( + &self, + public_keys: impl IntoIterator, + message: &[u8], + signature: &G2Element, + ) -> bool { + let mut g1_pointers = public_keys + .into_iter() + .map(|g1| g1.c_element) + .collect::>(); + + unsafe { + LegacySchemeMPLVerifySecure( + self.as_mut_ptr(), + g1_pointers.as_mut_ptr(), + g1_pointers.len(), + signature.c_element, + message.as_ptr() as *const _, + message.len(), + ) + } + } + + fn aggregate_verify<'a>( + &self, + public_keys: impl IntoIterator, + messages: impl IntoIterator, + signature: &G2Element, + ) -> bool { + let AggregateVerifyArgs { + mut g1_pointers, + mut messages_pointers, + messages_lengths: mut messages_lengthes, + } = prepare_aggregate_verify_args(public_keys, messages); + + unsafe { + LegacySchemeMPLAggregateVerify( + self.as_mut_ptr(), + g1_pointers.as_mut_ptr(), + g1_pointers.len(), + messages_pointers.as_mut_ptr() as *mut _, + messages_lengthes.as_mut_ptr() as *mut _, + messages_pointers.len(), + signature.c_element, + ) + } + } +} + +impl Drop for BasicSchemeMPL { + fn drop(&mut self) { + unsafe { BasicSchemeMPLFree(self.scheme) } + } +} + +pub struct AugSchemeMPL { + scheme: *mut c_void, +} + +impl AugSchemeMPL { + pub fn new() -> Self { + AugSchemeMPL { + scheme: unsafe { NewAugSchemeMPL() }, + } + } +} + +impl Scheme for AugSchemeMPL { + fn as_mut_ptr(&self) -> *mut c_void { + self.scheme + } + + fn sign(&self, private_key: &PrivateKey, message: &[u8]) -> G2Element { + G2Element { + c_element: unsafe { + AugSchemeMPLSign( + self.scheme, + private_key.as_mut_ptr(), + message.as_ptr() as *const _, + message.len(), + ) + }, + } + } + + fn verify(&self, public_key: &G1Element, message: &[u8], signature: &G2Element) -> bool { + unsafe { + AugSchemeMPLVerify( + self.scheme, + public_key.c_element, + message.as_ptr() as *const _, + message.len(), + signature.c_element, + ) + } + } + + fn aggregate_verify<'a>( + &self, + public_keys: impl IntoIterator, + messages: impl IntoIterator, + signature: &G2Element, + ) -> bool { + let AggregateVerifyArgs { + mut g1_pointers, + mut messages_pointers, + mut messages_lengths, + } = prepare_aggregate_verify_args(public_keys, messages); + + unsafe { + AugSchemeMPLAggregateVerify( + self.as_mut_ptr(), + g1_pointers.as_mut_ptr(), + g1_pointers.len(), + messages_pointers.as_mut_ptr() as *mut _, + messages_lengths.as_mut_ptr() as *mut _, + messages_pointers.len(), + signature.c_element, + ) + } + } +} + +impl Drop for AugSchemeMPL { + fn drop(&mut self) { + unsafe { AugSchemeMPLFree(self.scheme) } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + fn verify_aggregate(scheme: impl Scheme) { + let seed1 = b"seedweedseedweedseedweedseedweed"; + let seed2 = b"weedseedweedseedweedseedweedseed"; + let seed3 = b"seedseedseedseedweedweedweedweed"; + let seed4 = b"weedweedweedweedweedweedweedweed"; + + let private_key_1 = + PrivateKey::key_gen(&scheme, seed1).expect("unable to generate private key"); + let private_key_2 = + PrivateKey::key_gen(&scheme, seed2).expect("unable to generate private key"); + let private_key_3 = + PrivateKey::key_gen(&scheme, seed3).expect("unable to generate private key"); + let private_key_4 = + PrivateKey::key_gen(&scheme, seed4).expect("unable to generate private key"); + + let public_key_1 = private_key_1 + .g1_element() + .expect("unable to get public key"); + let public_key_2 = private_key_2 + .g1_element() + .expect("unable to get public key"); + let public_key_3 = private_key_3 + .g1_element() + .expect("unable to get public key"); + let public_key_4 = private_key_4 + .g1_element() + .expect("unable to get public key"); + + let message_1 = b"ayya"; + let message_2 = b"ayyb"; + let message_3 = b"ayyc"; + let message_4 = b"ayyd"; + + let signature_1 = scheme.sign(&private_key_1, message_1); + let signature_2 = scheme.sign(&private_key_2, message_2); + let signature_3 = scheme.sign(&private_key_3, message_3); + let signature_4 = scheme.sign(&private_key_4, message_4); + + let signature_agg = scheme.aggregate_sigs([&signature_1, &signature_2, &signature_3]); + + let verify = scheme.aggregate_verify( + [&public_key_1, &public_key_2, &public_key_3], + [message_1.as_ref(), message_2.as_ref(), message_3.as_ref()], + &signature_agg, + ); + assert!(verify); + + // Arbitrary trees of aggregates + let signature_agg_final = scheme.aggregate_sigs([&signature_agg, &signature_4]); + let verify_final = scheme.aggregate_verify( + [&public_key_1, &public_key_2, &public_key_3, &public_key_4], + [ + message_1.as_ref(), + message_2.as_ref(), + message_3.as_ref(), + message_4.as_ref(), + ], + &signature_agg_final, + ); + assert!(verify_final); + } + + #[test] + fn verify_aggregate_aug() { + verify_aggregate(AugSchemeMPL::new()); + } + + #[test] + fn verify_aggregate_basic() { + verify_aggregate(BasicSchemeMPL::new()); + } + + #[test] + fn verify_aggregate_legacy() { + verify_aggregate(LegacySchemeMPL::new()); + } +} diff --git a/rust-bindings/bls-signatures/src/utils.rs b/rust-bindings/bls-signatures/src/utils.rs new file mode 100644 index 0000000000..8461e25e93 --- /dev/null +++ b/rust-bindings/bls-signatures/src/utils.rs @@ -0,0 +1,71 @@ +use core::slice; +use std::{ + ffi::{c_void, CStr}, + ops::Deref, +}; + +use bls_dash_sys::{GetLastErrorMsg, SecAllocBytes, SecFree}; + +use crate::BlsError; + +pub(crate) fn c_err_to_result(f: F) -> Result +where + F: FnOnce(&mut bool) -> T, +{ + let mut did_error = false; + let result = f(&mut did_error); + + if did_error { + let error_message = unsafe { CStr::from_ptr(GetLastErrorMsg()) }; + Err(BlsError { + msg: String::from_utf8_lossy(error_message.to_bytes()).into_owned(), + }) + } else { + Ok(result) + } +} + +pub struct SecureBox { + c_sec_alloc: *mut u8, + len: usize, +} + +impl SecureBox { + #[allow(dead_code)] + pub(crate) fn new(len: usize) -> Self { + SecureBox { + c_sec_alloc: unsafe { SecAllocBytes(len) }, + len, + } + } + + pub(crate) unsafe fn from_ptr(ptr: *mut u8, len: usize) -> Self { + SecureBox { + c_sec_alloc: ptr, + len, + } + } + + // Somewhere it returns *mut c_void + pub(crate) fn as_mut_ptr(&mut self) -> *mut c_void { + self.c_sec_alloc as *mut c_void + } + + pub fn as_slice(&self) -> &[u8] { + unsafe { slice::from_raw_parts(self.c_sec_alloc, self.len) } + } +} + +impl Deref for SecureBox { + type Target = [u8]; + + fn deref(&self) -> &Self::Target { + self.as_slice() + } +} + +impl Drop for SecureBox { + fn drop(&mut self) { + unsafe { SecFree(self.as_mut_ptr()) } + } +} diff --git a/rust-bindings/example/Cargo.toml b/rust-bindings/example/Cargo.toml new file mode 100644 index 0000000000..8cbc6b7d91 --- /dev/null +++ b/rust-bindings/example/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "example" +version = "0.1.0" +edition = "2021" + +[dependencies] +bls-signatures = { path = "../bls-signatures" } diff --git a/rust-bindings/example/src/main.rs b/rust-bindings/example/src/main.rs new file mode 100644 index 0000000000..afc7c27cbb --- /dev/null +++ b/rust-bindings/example/src/main.rs @@ -0,0 +1,51 @@ +use bls_signatures::{bip32::ExtendedPrivateKey, LegacySchemeMPL, Scheme}; + +const SEED: &'static [u8] = b"seedweedseedweedseedweedseedweed"; + +fn check_bip32_hd_keys() { + println!("Check BIP32 hierarchical deterministic keys work"); + + let private_key = + ExtendedPrivateKey::from_seed(SEED).expect("cannot generate extended private key"); + let public_key = private_key + .extended_public_key() + .expect("cannot get extended public key"); + + let private_child = private_key.private_child(1337); + let private_grandchild = private_child.private_child(420); + + let public_child = public_key.public_child(1337); + let public_grandchild = public_child.public_child(420); + + assert_eq!( + public_grandchild, + private_grandchild + .extended_public_key() + .expect("cannot get extended public key") + ); +} + +fn check_bip32_legacy_scheme() { + println!("Check BIP32 signing works"); + + let private_key = + ExtendedPrivateKey::from_seed(SEED).expect("cannot generate extended private key"); + let public_key = private_key + .extended_public_key() + .expect("cannot get extended public key"); + + let scheme = LegacySchemeMPL::new(); + let message = b"dash is og"; + let signature = scheme.sign(&private_key.private_key(), message); + + assert!(scheme.verify(&public_key.public_key(), message, &signature)); +} + +fn main() { + println!("Run some checks to see if everything is linked up to original BLS library:"); + + check_bip32_hd_keys(); + check_bip32_legacy_scheme(); + + println!("All checks passed!"); +} diff --git a/setjmp_patch.diff b/setjmp_patch.diff new file mode 100644 index 0000000000..f4a5c80f1c --- /dev/null +++ b/setjmp_patch.diff @@ -0,0 +1,41 @@ +diff --git a/include/relic_err.h b/include/relic_err.h +index e16f71fe..a4adb107 100644 +--- a/include/relic_err.h ++++ b/include/relic_err.h +@@ -33,7 +33,6 @@ + #define RLC_ERR_H + + #include +-#include + #include + #include + #include +@@ -43,6 +42,10 @@ + #include "relic_util.h" + #include "relic_label.h" + ++#ifdef CHECK ++#include ++#endif ++ + /*============================================================================*/ + /* Constant definitions */ + /*============================================================================*/ +@@ -94,6 +97,8 @@ enum errors { + */ + typedef int err_t; + ++#ifdef CHECK ++ + /** + * Type that describes an error status, including the error code and the program + * location where the error occurred. +@@ -107,6 +112,8 @@ typedef struct _sts_t { + int block; + } sts_t; + ++#endif ++ + /*============================================================================*/ + /* Macro definitions */ + /*============================================================================*/ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a021e7894f..c3c1abd759 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -11,8 +11,7 @@ add_library(dashbls ${CMAKE_CURRENT_SOURCE_DIR}/extendedpublickey.cpp ${CMAKE_CURRENT_SOURCE_DIR}/legacy.cpp ${CMAKE_CURRENT_SOURCE_DIR}/schemes.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/threshold.cpp -) + ${CMAKE_CURRENT_SOURCE_DIR}/threshold.cpp) target_include_directories(dashbls PUBLIC diff --git a/src/elements.cpp b/src/elements.cpp index d53426da02..278af8cd8f 100644 --- a/src/elements.cpp +++ b/src/elements.cpp @@ -98,6 +98,14 @@ G1Element G1Element::FromNative(const g1_t element) return ele; } +G1Element G1Element::Copy() { + G1Element ele; + g1_copy(ele.p, this->p); + + return ele; +} + + G1Element G1Element::FromMessage(const std::vector& message, const uint8_t* dst, int dst_len) @@ -246,6 +254,7 @@ G2Element G2Element::FromBytesUnchecked(Bytes const bytes, const bool fLegacy) if (fLegacy) { std::memcpy(buffer + 1, bytes.begin(), G2Element::SIZE); + buffer[0] = 0x00; } else { std::memcpy(buffer + 1, bytes.begin() + G2Element::SIZE / 2, G2Element::SIZE / 2); std::memcpy(buffer + 1 + G2Element::SIZE / 2, bytes.begin(), G2Element::SIZE / 2); @@ -358,6 +367,14 @@ void G2Element::ToNative(g2_t output) const { g2_copy(output, (g2_st*)q); } +G2Element G2Element::Copy() { + G2Element ele; + g2_copy(ele.q, this->q); + + return ele; +} + + G2Element G2Element::Negate() const { G2Element ans; diff --git a/src/test.cpp b/src/test.cpp index 3102c7eeae..51d84706a8 100644 --- a/src/test.cpp +++ b/src/test.cpp @@ -56,7 +56,7 @@ void TestHKDF(string ikm_hex, string salt_hex, string info_hex, string prk_expec TEST_CASE("class PrivateKey") { uint8_t buffer[PrivateKey::PRIVATE_KEY_SIZE]; - memcmp(buffer, getRandomSeed().data(), PrivateKey::PRIVATE_KEY_SIZE); + memcpy(buffer, getRandomSeed().data(), PrivateKey::PRIVATE_KEY_SIZE); SECTION("Copy {constructor|assignment operator}") { PrivateKey pk1 = PrivateKey::RandomPrivateKey(); PrivateKey pk2 = PrivateKey::RandomPrivateKey(); From a891c78654538c477fba0d8918d81005cdcd9601 Mon Sep 17 00:00:00 2001 From: UdjinM6 Date: Wed, 28 Jun 2023 23:44:03 +0300 Subject: [PATCH 3/3] build: stop tracking cmake dependency relic_conf.h.in This reverts commit 0b3ab8d5e9e19fc9b259dcb2a061f6c765957427. --- .../depends/relic/include/relic_conf.h.in | 717 ------------------ 1 file changed, 717 deletions(-) delete mode 100644 src/dashbls/depends/relic/include/relic_conf.h.in diff --git a/src/dashbls/depends/relic/include/relic_conf.h.in b/src/dashbls/depends/relic/include/relic_conf.h.in deleted file mode 100644 index 7db6f5b509..0000000000 --- a/src/dashbls/depends/relic/include/relic_conf.h.in +++ /dev/null @@ -1,717 +0,0 @@ -/* - * RELIC is an Efficient LIbrary for Cryptography - * Copyright (c) 2009 RELIC Authors - * - * This file is part of RELIC. RELIC is legal property of its developers, - * whose names are not listed here. Please refer to the COPYRIGHT file - * for contact information. - * - * RELIC is free software; you can redistribute it and/or modify it under the - * terms of the version 2.1 (or later) of the GNU Lesser General Public License - * as published by the Free Software Foundation; or version 2.0 of the Apache - * License as published by the Apache Software Foundation. See the LICENSE files - * for more details. - * - * RELIC is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - * A PARTICULAR PURPOSE. See the LICENSE files for more details. - * - * You should have received a copy of the GNU Lesser General Public or the - * Apache License along with RELIC. If not, see - * or . - */ - -/** - * @file - * - * Project configuration. - * - * @version $Id: relic_conf.h.in 45 2009-07-04 23:45:48Z dfaranha $ - * @ingroup relic - */ - -#ifndef RLC_CONF_H -#define RLC_CONF_H - -/** Project version. */ -#define RLC_VERSION "@VERSION@" - -/** Debugging support. */ -#cmakedefine DEBUG -/** Profiling support. */ -#cmakedefine PROFL -/** Error handling support. */ -#cmakedefine CHECK -/** Verbose error messages. */ -#cmakedefine VERBS -/** Build with overhead estimation. */ -#cmakedefine OVERH -/** Build documentation. */ -#cmakedefine DOCUM -/** Build only the selected algorithms. */ -#cmakedefine STRIP -/** Build with printing disabled. */ -#cmakedefine QUIET -/** Build with colored output. */ -#cmakedefine COLOR -/** Build with big-endian support. */ -#cmakedefine BIGED -/** Build shared library. */ -#cmakedefine SHLIB -/** Build static library. */ -#cmakedefine STLIB - -/** Number of times each test is ran. */ -#define TESTS @TESTS@ -/** Number of times each benchmark is ran. */ -#define BENCH @BENCH@ -/** Number of available cores. */ -#define CORES @CORES@ - -/** Atmel AVR ATMega128 8-bit architecture. */ -#define AVR 1 -/** MSP430 16-bit architecture. */ -#define MSP 2 -/** ARM 32-bit architecture. */ -#define ARM 3 -/** Intel x86-compatible 32-bit architecture. */ -#define X86 4 -/** AMD64-compatible 64-bit architecture. */ -#define X64 5 -/** Architecture. */ -#cmakedefine ARCH @ARCH@ - -/** Size of word in this architecture. */ -#define WSIZE @WSIZE@ - -/** Byte boundary to align digit vectors. */ -#define ALIGN @ALIGN@ - -/** Build multiple precision integer module. */ -#cmakedefine WITH_BN -/** Build prime field module. */ -#cmakedefine WITH_FP -/** Build prime field extension module. */ -#cmakedefine WITH_FPX -/** Build binary field module. */ -#cmakedefine WITH_FB -/** Build prime elliptic curve module. */ -#cmakedefine WITH_EP -/** Build prime field extension elliptic curve module. */ -#cmakedefine WITH_EPX -/** Build binary elliptic curve module. */ -#cmakedefine WITH_EB -/** Build elliptic Edwards curve module. */ -#cmakedefine WITH_ED -/** Build elliptic curve cryptography module. */ -#cmakedefine WITH_EC -/** Build pairings over prime curves module. */ -#cmakedefine WITH_PP -/** Build pairing-based cryptography module. */ -#cmakedefine WITH_PC -/** Build block ciphers. */ -#cmakedefine WITH_BC -/** Build hash functions. */ -#cmakedefine WITH_MD -/** Build cryptographic protocols. */ -#cmakedefine WITH_CP -/** Build Multi-party computation primitives. */ -#cmakedefine WITH_MPC - -/** Easy C-only backend. */ -#define EASY 1 -/** GMP backend. */ -#define GMP 2 -/** GMP constant-time backend. */ -#define GMP_SEC 3 -/** Arithmetic backend. */ -#define ARITH @ARITH@ - -/** Required precision in bits. */ -#define BN_PRECI @BN_PRECI@ -/** A multiple precision integer can store w words. */ -#define SINGLE 0 -/** A multiple precision integer can store the result of an addition. */ -#define CARRY 1 -/** A multiple precision integer can store the result of a multiplication. */ -#define DOUBLE 2 -/** Effective size of a multiple precision integer. */ -#define BN_MAGNI @BN_MAGNI@ -/** Number of Karatsuba steps. */ -#define BN_KARAT @BN_KARAT@ - -/** Schoolbook multiplication. */ -#define BASIC 1 -/** Comba multiplication. */ -#define COMBA 2 -/** Chosen multiple precision multiplication method. */ -#define BN_MUL @BN_MUL@ - -/** Schoolbook squaring. */ -#define BASIC 1 -/** Comba squaring. */ -#define COMBA 2 -/** Reuse multiplication for squaring. */ -#define MULTP 4 -/** Chosen multiple precision multiplication method. */ -#define BN_SQR @BN_SQR@ - -/** Division modular reduction. */ -#define BASIC 1 -/** Barrett modular reduction. */ -#define BARRT 2 -/** Montgomery modular reduction. */ -#define MONTY 3 -/** Pseudo-Mersenne modular reduction. */ -#define PMERS 4 -/** Chosen multiple precision modular reduction method. */ -#define BN_MOD @BN_MOD@ - -/** Binary modular exponentiation. */ -#define BASIC 1 -/** Sliding window modular exponentiation. */ -#define SLIDE 2 -/** Montgomery powering ladder. */ -#define MONTY 3 -/** Chosen multiple precision modular exponentiation method. */ -#define BN_MXP @BN_MXP@ - -/** Basic Euclidean GCD Algorithm. */ -#define BASIC 1 -/** Lehmer's fast GCD Algorithm. */ -#define LEHME 2 -/** Stein's binary GCD Algorithm. */ -#define STEIN 3 -/** Chosen multiple precision greatest common divisor method. */ -#define BN_GCD @BN_GCD@ - -/** Basic prime generation. */ -#define BASIC 1 -/** Safe prime generation. */ -#define SAFEP 2 -/** Strong prime generation. */ -#define STRON 3 -/** Chosen prime generation algorithm. */ -#define BN_GEN @BN_GEN@ - -/** Multiple precision arithmetic method */ -#define BN_METHD "@BN_METHD@" - -/** Prime field size in bits. */ -#define FP_PRIME @FP_PRIME@ -/** Number of Karatsuba steps. */ -#define FP_KARAT @FP_KARAT@ -/** Prefer Pseudo-Mersenne primes over random primes. */ -#cmakedefine FP_PMERS -/** Use -1 as quadratic non-residue. */ -#cmakedefine FP_QNRES -/** Width of window processing for exponentiation methods. */ -#define FP_WIDTH @FP_WIDTH@ - -/** Schoolbook addition. */ -#define BASIC 1 -/** Integrated modular addtion. */ -#define INTEG 3 -/** Chosen prime field multiplication method. */ -#define FP_ADD @FP_ADD@ - -/** Schoolbook multiplication. */ -#define BASIC 1 -/** Comba multiplication. */ -#define COMBA 2 -/** Integrated modular multiplication. */ -#define INTEG 3 -/** Chosen prime field multiplication method. */ -#define FP_MUL @FP_MUL@ - -/** Schoolbook squaring. */ -#define BASIC 1 -/** Comba squaring. */ -#define COMBA 2 -/** Integrated modular squaring. */ -#define INTEG 3 -/** Reuse multiplication for squaring. */ -#define MULTP 4 -/** Chosen prime field multiplication method. */ -#define FP_SQR @FP_SQR@ - -/** Division-based reduction. */ -#define BASIC 1 -/** Fast reduction modulo special form prime. */ -#define QUICK 2 -/** Montgomery modular reduction. */ -#define MONTY 3 -/** Chosen prime field reduction method. */ -#define FP_RDC @FP_RDC@ - -/** Inversion by Fermat's Little Theorem. */ -#define BASIC 1 -/** Binary inversion. */ -#define BINAR 2 -/** Integrated modular multiplication. */ -#define MONTY 3 -/** Extended Euclidean algorithm. */ -#define EXGCD 4 -/** Constant-time inversion by Bernstein-Yang division steps. */ -#define DIVST 5 -/** Use implementation provided by the lower layer. */ -#define LOWER 8 -/** Chosen prime field inversion method. */ -#define FP_INV @FP_INV@ - -/** Binary modular exponentiation. */ -#define BASIC 1 -/** Sliding window modular exponentiation. */ -#define SLIDE 2 -/** Constant-time Montgomery powering ladder. */ -#define MONTY 3 -/** Chosen multiple precision modular exponentiation method. */ -#define FP_EXP @FP_EXP@ - -/** Prime field arithmetic method */ -#define FP_METHD "@FP_METHD@" - -/** Basic quadratic extension field arithmetic. */ -#define BASIC 1 -/** Integrated extension field arithmetic. */ -#define INTEG 3 -/* Chosen extension field arithmetic method. */ -#define FPX_QDR @FPX_QDR@ - -/** Basic cubic extension field arithmetic. */ -#define BASIC 1 -/** Integrated extension field arithmetic. */ -#define INTEG 3 -/* Chosen extension field arithmetic method. */ -#define FPX_CBC @FPX_CBC@ - -/** Basic quadratic extension field arithmetic. */ -#define BASIC 1 -/** Lazy-reduced extension field arithmetic. */ -#define LAZYR 2 -/* Chosen extension field arithmetic method. */ -#define FPX_RDC @FPX_RDC@ - -/** Prime extension field arithmetic method */ -#define FPX_METHD "@FPX_METHD@" - -/** Irreducible polynomial size in bits. */ -#define FB_POLYN @FB_POLYN@ -/** Number of Karatsuba steps. */ -#define FB_KARAT @FB_KARAT@ -/** Prefer trinomials over pentanomials. */ -#cmakedefine FB_TRINO -/** Prefer square-root friendly polynomials. */ -#cmakedefine FB_SQRTF -/** Precompute multiplication table for sqrt(z). */ -#cmakedefine FB_PRECO -/** Width of window processing for exponentiation methods. */ -#define FB_WIDTH @FB_WIDTH@ - -/** Shift-and-add multiplication. */ -#define BASIC 1 -/** Lopez-Dahab multiplication. */ -#define LODAH 2 -/** Integrated modular multiplication. */ -#define INTEG 3 -/** Chosen binary field multiplication method. */ -#define FB_MUL @FB_MUL@ - -/** Basic squaring. */ -#define BASIC 1 -/** Table-based squaring. */ -#define QUICK 2 -/** Integrated modular squaring. */ -#define INTEG 3 -/** Chosen binary field squaring method. */ -#define FB_SQR @FB_SQR@ - -/** Shift-and-add modular reduction. */ -#define BASIC 1 -/** Fast reduction modulo a trinomial or pentanomial. */ -#define QUICK 2 -/** Chosen binary field modular reduction method. */ -#define FB_RDC @FB_RDC@ - -/** Square root by repeated squaring. */ -#define BASIC 1 -/** Fast square root extraction. */ -#define QUICK 2 -/** Chosen binary field modular reduction method. */ -#define FB_SRT @FB_SRT@ - -/** Trace by repeated squaring. */ -#define BASIC 1 -/** Fast trace computation. */ -#define QUICK 2 -/** Chosen trace computation method. */ -#define FB_TRC @FB_TRC@ - -/** Solve by half-trace computation. */ -#define BASIC 1 -/** Solve with precomputed half-traces. */ -#define QUICK 2 -/** Chosen method to solve a quadratic equation. */ -#define FB_SLV @FB_SLV@ - -/** Inversion by Fermat's Little Theorem. */ -#define BASIC 1 -/** Binary inversion. */ -#define BINAR 2 -/** Almost inverse algorithm. */ -#define ALMOS 3 -/** Extended Euclidean algorithm. */ -#define EXGCD 4 -/** Itoh-Tsuji inversion. */ -#define ITOHT 5 -/** Hardware-friendly inversion by Brunner-Curiger-Hofstetter.*/ -#define BRUCH 6 -/** Constant-time version of almost inverse. */ -#define CTAIA 7 -/** Use implementation provided by the lower layer. */ -#define LOWER 8 -/** Chosen binary field inversion method. */ -#define FB_INV @FB_INV@ - -/** Binary modular exponentiation. */ -#define BASIC 1 -/** Sliding window modular exponentiation. */ -#define SLIDE 2 -/** Constant-time Montgomery powering ladder. */ -#define MONTY 3 -/** Chosen multiple precision modular exponentiation method. */ -#define FB_EXP @FB_EXP@ - -/** Iterated squaring/square-root by consecutive squaring/square-root. */ -#define BASIC 1 -/** Iterated squaring/square-root by table-based method. */ -#define QUICK 2 -/** Chosen method to solve a quadratic equation. */ -#define FB_ITR @FB_ITR@ - -/** Binary field arithmetic method */ -#define FB_METHD "@FB_METHD@" - -/** Support for ordinary curves. */ -#cmakedefine EP_PLAIN -/** Support for supersingular curves. */ -#cmakedefine EP_SUPER -/** Support for prime curves with efficient endormorphisms. */ -#cmakedefine EP_ENDOM -/** Use mixed coordinates. */ -#cmakedefine EP_MIXED -/** Build precomputation table for generator. */ -#cmakedefine EP_PRECO -/** Enable isogeny map for SSWU map-to-curve. */ -#cmakedefine EP_CTMAP -/** Width of precomputation table for fixed point methods. */ -#define EP_DEPTH @EP_DEPTH@ -/** Width of window processing for unknown point methods. */ -#define EP_WIDTH @EP_WIDTH@ - -/** Affine coordinates. */ -#define BASIC 1 -/** Projective coordinates. */ -#define PROJC 2 -/** Jacobian coordinates. */ -#define JACOB 3 -/** Chosen prime elliptic curve coordinate method. */ -#define EP_ADD @EP_ADD@ - -/** Binary point multiplication. */ -#define BASIC 1 -/** Sliding window. */ -#define SLIDE 2 -/** Montgomery powering ladder. */ -#define MONTY 3 -/** Left-to-right Width-w NAF. */ -#define LWNAF 4 -/** Left-to-right Width-w NAF. */ -#define LWREG 5 -/** Chosen prime elliptic curve point multiplication method. */ -#define EP_MUL @EP_MUL@ - -/** Binary point multiplication. */ -#define BASIC 1 -/** Single-table comb method. */ -#define COMBS 2 -/** Double-table comb method. */ -#define COMBD 3 -/** Left-to-right Width-w NAF. */ -#define LWNAF 4 -/** Chosen prime elliptic curve point multiplication method. */ -#define EP_FIX @EP_FIX@ - -/** Basic simultaneouns point multiplication. */ -#define BASIC 1 -/** Shamir's trick. */ -#define TRICK 2 -/** Interleaving of w-(T)NAFs. */ -#define INTER 3 -/** Joint sparse form. */ -#define JOINT 4 -/** Chosen prime elliptic curve simulteanous point multiplication method. */ -#define EP_SIM @EP_SIM@ - -/** Prime elliptic curve arithmetic method. */ -#define EP_METHD "@EP_METHD@" - -/** Support for ordinary curves without endormorphisms. */ -#cmakedefine EB_PLAIN -/** Support for Koblitz anomalous binary curves. */ -#cmakedefine EB_KBLTZ -/** Use mixed coordinates. */ -#cmakedefine EB_MIXED -/** Build precomputation table for generator. */ -#cmakedefine EB_PRECO -/** Width of precomputation table for fixed point methods. */ -#define EB_DEPTH @EB_DEPTH@ -/** Width of window processing for unknown point methods. */ -#define EB_WIDTH @EB_WIDTH@ - -/** Binary elliptic curve arithmetic method. */ -#define EB_METHD "@EB_METHD@" - -/** Affine coordinates. */ -#define BASIC 1 -/** López-Dahab Projective coordinates. */ -#define PROJC 2 -/** Chosen binary elliptic curve coordinate method. */ -#define EB_ADD @EB_ADD@ - -/** Binary point multiplication. */ -#define BASIC 1 -/** L�pez-Dahab point multiplication. */ -#define LODAH 2 -/** Halving. */ -#define HALVE 3 -/** Left-to-right width-w (T)NAF. */ -#define LWNAF 4 -/** Right-to-left width-w (T)NAF. */ -#define RWNAF 5 -/** Chosen binary elliptic curve point multiplication method. */ -#define EB_MUL @EB_MUL@ - -/** Binary point multiplication. */ -#define BASIC 1 -/** Single-table comb method. */ -#define COMBS 2 -/** Double-table comb method. */ -#define COMBD 3 -/** Left-to-right Width-w NAF. */ -#define LWNAF 4 -/** Chosen binary elliptic curve point multiplication method. */ -#define EB_FIX @EB_FIX@ - -/** Basic simultaneouns point multiplication. */ -#define BASIC 1 -/** Shamir's trick. */ -#define TRICK 2 -/** Interleaving of w-(T)NAFs. */ -#define INTER 3 -/** Joint sparse form. */ -#define JOINT 4 -/** Chosen binary elliptic curve simulteanous point multiplication method. */ -#define EB_SIM @EB_SIM@ - -/** Build precomputation table for generator. */ -#cmakedefine ED_PRECO -/** Width of precomputation table for fixed point methods. */ -#define ED_DEPTH @ED_DEPTH@ -/** Width of window processing for unknown point methods. */ -#define ED_WIDTH @ED_WIDTH@ - -/** Edwards elliptic curve arithmetic method. */ -#define ED_METHD "@ED_METHD@" - -/** Affine coordinates. */ -#define BASIC 1 -/** Simple projective twisted Edwards coordinates */ -#define PROJC 2 -/** Extended projective twisted Edwards coordinates */ -#define EXTND 3 -/** Chosen binary elliptic curve coordinate method. */ -#define ED_ADD @ED_ADD@ - -/** Binary point multiplication. */ -#define BASIC 1 -/** Sliding window. */ -#define SLIDE 2 -/** Montgomery powering ladder. */ -#define MONTY 3 -/** Left-to-right Width-w NAF. */ -#define LWNAF 4 -/** Left-to-right Width-w NAF. */ -#define LWREG 5 -/** Chosen prime elliptic twisted Edwards curve point multiplication method. */ -#define ED_MUL @ED_MUL@ - -/** Binary point multiplication. */ -#define BASIC 1 -/** Single-table comb method. */ -#define COMBS 2 -/** Double-table comb method. */ -#define COMBD 3 -/** Left-to-right Width-w NAF. */ -#define LWNAF 4 -/** Chosen prime elliptic twisted Edwards curve point multiplication method. */ -#define ED_FIX @ED_FIX@ - -/** Basic simultaneouns point multiplication. */ -#define BASIC 1 -/** Shamir's trick. */ -#define TRICK 2 -/** Interleaving of w-(T)NAFs. */ -#define INTER 3 -/** Joint sparse form. */ -#define JOINT 4 -/** Chosen prime elliptic curve simulteanous point multiplication method. */ -#define ED_SIM @ED_SIM@ - -/** Prime curves. */ -#define PRIME 1 -/** Binary curves. */ -#define CHAR2 2 -/** Edwards curves */ -#define EDDIE 3 -/** Chosen elliptic curve type. */ -#define EC_CUR @EC_CUR@ - -/** Chosen elliptic curve cryptography method. */ -#define EC_METHD "@EC_METHD@" -/** Prefer curves with efficient endomorphisms. */ -#cmakedefine EC_ENDOM - -/** Basic quadratic extension field arithmetic. */ -#define BASIC 1 -/** Lazy-reduced extension field arithmetic. */ -#define LAZYR 2 -/* Chosen extension field arithmetic method. */ -#define PP_EXT @PP_EXT@ - -/** Bilinear pairing method. */ -#define PP_METHD "@PP_METHD@" - -/** Tate pairing. */ -#define TATEP 1 -/** Weil pairing. */ -#define WEILP 2 -/** Optimal ate pairing. */ -#define OATEP 3 -/** Chosen pairing method over prime elliptic curves. */ -#define PP_MAP @PP_MAP@ - -/** SHA-224 hash function. */ -#define SH224 2 -/** SHA-256 hash function. */ -#define SH256 3 -/** SHA-384 hash function. */ -#define SH384 4 -/** SHA-512 hash function. */ -#define SH512 5 -/** BLAKE2s-160 hash function. */ -#define B2S160 6 -/** BLAKE2s-256 hash function. */ -#define B2S256 7 -/** Chosen hash function. */ -#define MD_MAP @MD_MAP@ - -/** Choice of hash function. */ -#define MD_METHD "@MD_METHD@" - -/** Chosen RSA method. */ -#cmakedefine CP_CRT -/** RSA without padding. */ -#define BASIC 1 -/** RSA PKCS#1 v1.5 padding. */ -#define PKCS1 2 -/** RSA PKCS#1 v2.1 padding. */ -#define PKCS2 3 -/** Chosen RSA padding method. */ -#define CP_RSAPD @CP_RSAPD@ - -/** Automatic memory allocation. */ -#define AUTO 1 -/** Dynamic memory allocation. */ -#define DYNAMIC 2 -/** Chosen memory allocation policy. */ -#define ALLOC @ALLOC@ - -/** NIST HASH-DRBG generator. */ -#define HASHD 1 -/** Intel RdRand instruction. */ -#define RDRND 2 -/** Operating system underlying generator. */ -#define UDEV 3 -/** Override library generator with the callback. */ -#define CALL 4 -/** Chosen random generator. */ -#define RAND @RAND@ - -/** Standard C library generator. */ -#define LIBC 1 -/** Intel RdRand instruction. */ -#define RDRND 2 -/** Device node generator. */ -#define UDEV 3 -/** Use Windows' CryptGenRandom. */ -#define WCGR 4 -/** Chosen random generator seeder. */ -#cmakedefine SEED @SEED@ - -/** GNU/Linux operating system. */ -#define LINUX 1 -/** FreeBSD operating system. */ -#define FREEBSD 2 -/** Windows operating system. */ -#define MACOSX 3 -/** Windows operating system. */ -#define WINDOWS 4 -/** Android operating system. */ -#define DROID 5 -/** Arduino platform. */ -#define DUINO 6 -/** OpenBSD operating system. */ -#define OPENBSD 7 -/** Detected operation system. */ -#cmakedefine OPSYS @OPSYS@ - -/** OpenMP multithreading support. */ -#define OPENMP 1 -/** POSIX multithreading support. */ -#define PTHREAD 2 -/** Chosen multithreading API. */ -#cmakedefine MULTI @MULTI@ - -/** Per-process high-resolution timer. */ -#define HREAL 1 -/** Per-process high-resolution timer. */ -#define HPROC 2 -/** Per-thread high-resolution timer. */ -#define HTHRD 3 -/** POSIX-compatible timer. */ -#define POSIX 4 -/** ANSI-compatible timer. */ -#define ANSI 5 -/** Cycle-counting timer. */ -#define CYCLE 6 -/** Performance monitoring framework. */ -#define PERF 7 -/** Chosen timer. */ -#cmakedefine TIMER @TIMER@ - -/** Prefix to identity this build of the library. */ -#cmakedefine LABEL @LABEL@ - -#ifndef ASM - -#include "relic_label.h" - -/** - * Prints the project options selected at build time. - */ -void conf_print(void); - -#endif /* ASM */ - -#endif /* !RLC_CONF_H */