Git Product home page Git Product logo

bls's People

Contributors

antouhou avatar aqk avatar arvidn avatar awice avatar codablock avatar coolaj86 avatar dependabot[bot] avatar eyalron33 avatar hoffmang9 avatar jonspock avatar kayabanerve avatar mariano54 avatar mdz avatar mogisawa avatar n1000 avatar nazar-pc avatar nmarley avatar quantumexplorer avatar raycoms avatar sbellem avatar udjinm6 avatar wjblanke avatar wmerfalen avatar xdustinface avatar

Watchers

 avatar

bls's Issues

Publish releases using standard host triple

There are two standards that I'm aware of.

The first is how Rust and Zig do it, which I think is the C-style language quasi-posix standard:

<thing>-<version>-<cpu>-<vendor>-<os>[-toolchain]<.ext>
bls-1.0.0-x86_64-pc-windows-msvc.zip
bls-1.0.0-aarch64-unknown-linux-gnu.tar.gz
bls-1.0.0-x86_64-unknown-linux-musl.tar.gz

The second is how GoReleaser does it, which is basically just omitting "vendor" and "toolchain" and using "mac" rather than "darwin" and "amd64" and "arm64" rather than "x86_64" and "aarch64", and using "_" more than "-". Perhaps more human friendly, but perhaps not as posix-y:

bls_1.0.0_mac_arm64.tar.gz
bls_1.0.0_windows_arm64.zip
bls_1.0.0_linux_amd64.tar.gz

Since this is a C-family CLI tool, the Rust / Zig style is probably the better choice.

Create a standalone CLI tool that generates BLS keys

  • given the same seed, must output the same key as dashpay/bls-signatures
  • repo with README sufficient for replicating results should be added to github.com/dashhive/

Repos

Summary (from Walker Ford)

The dash-cli tool is implemented in the dash monolith repo. The bls generate function calls into the Chia network's BLS implementation (bls-signatures), which is a wrapper over the relic crypto toolkit.

Calling dash-cli bls generate will invoke the function ble_generate() in the dash repo, which will generate a new key with MakeNewKey() and then output the secret and public keys.

MakeNewKey() creates a random seed with GetStrongRandBytes().

From the seed, the private key is generated through bls::PrivateKey::FromBytes(), in the bls-signatures repo.

FromBytes() calls into the relic repo with several functions, inlcuding bn_read_bin(), bn_new(), g1_get_ord().

The public key is derived from the private key with the function CBLSSecretKey::GetPublicKey() in the dash repo, which calls PrivateKey::GetG1Element() in the bls-signatures repo.

GetG1Eleent() calls into the relic repo with several functions, including g1_mul_gen(), which creates the public key.

All of the BLS magic is happening in those relic functions.

Once those functions are understood, it might be worth comparing against the pure JS or pure GO BLS libraries:

Implmeentation

Implementation of dash-cli bls generate.

Relevant code has been copy/pasted from each of the three reposistories. Most, but not every, relic function is present.

// rpcevo.cpp (dash)
// line 1206
UniValue bls_generate(const JSONRPCRequest& request)
{
    if (request.fHelp || request.params.size() != 1) {
        bls_generate_help();
    }

    CBLSSecretKey sk;
    sk.MakeNewKey();

    UniValue ret(UniValue::VOBJ);
    ret.pushKV("secret", sk.ToString());
    ret.pushKV("public", sk.GetPublicKey().ToString());
    return ret;
}
// bls.cpp (dash)
// line 59
void CBLSSecretKey::MakeNewKey()
{
    unsigned char buf[32];
    while (true) {
        GetStrongRandBytes(buf, sizeof(buf));
        try {
            impl = bls::PrivateKey::FromBytes(bls::Bytes((const uint8_t*)buf, SerSize));
            break;
        } catch (...) {
        }
    }
    fValid = true;
    cachedHash.SetNull();
}
// random.cpp (dash)
// line 318
void GetStrongRandBytes(unsigned char* out, int num)
{
    assert(num <= 32);
    CSHA512 hasher;
    unsigned char buf[64];

    // First source: OpenSSL's RNG
    RandAddSeedPerfmon();
    GetRandBytes(buf, 32);
    hasher.Write(buf, 32);

    // Second source: OS RNG
    GetOSRand(buf);
    hasher.Write(buf, 32);

    // Third source: HW RNG, if available.
    if (GetHWRand(buf)) {
        hasher.Write(buf, 32);
    }

    // Combine with and update state
    {
        std::unique_lock<std::mutex> lock(cs_rng_state);
        hasher.Write(rng_state, sizeof(rng_state));
        hasher.Write((const unsigned char*)&rng_counter, sizeof(rng_counter));
        ++rng_counter;
        hasher.Finalize(buf);
        memcpy(rng_state, buf + 32, 32);
    }

    // Produce output
    memcpy(out, buf, num);
    memory_cleanse(buf, 64);
}
// util.hpp
// line 27
namespace bls {

class BLS;

class Bytes {
    const uint8_t* pData;
    const size_t nSize;

public:
    explicit Bytes(const uint8_t* pDataIn, const size_t nSizeIn)
        : pData(pDataIn), nSize(nSizeIn)
    {
    }
    explicit Bytes(const std::vector<uint8_t>& vecBytes)
        : pData(vecBytes.data()), nSize(vecBytes.size())
    {
    }

    inline const uint8_t* begin() const { return pData; }
    inline const uint8_t* end() const { return pData + nSize; }

    inline size_t size() const { return nSize; }

    const uint8_t& operator[](const int nIndex) const { return pData[nIndex]; }
};
// ...
}
// privatekey.cpp (bls-signatures)
// line 21
PrivateKey PrivateKey::FromBytes(const Bytes& bytes, bool modOrder)
{
    if (bytes.size() != PRIVATE_KEY_SIZE) {
        throw std::invalid_argument("PrivateKey::FromBytes: Invalid size");
    }

    PrivateKey k;
    bn_read_bin(k.keydata, bytes.begin(), PrivateKey::PRIVATE_KEY_SIZE);
    bn_t ord;
    bn_new(ord);
    g1_get_ord(ord);
    if (modOrder) {
        bn_mod_basic(k.keydata, k.keydata, ord);
    } else {
        if (bn_cmp(k.keydata, ord) > 0) {
            throw std::invalid_argument(
                "PrivateKey byte data must be less than the group order");
        }
    }
    return k;
}
// bls.h (dash)
// line 225
class CBLSSecretKey : public CBLSWrapper<bls::PrivateKey, BLS_CURVE_SECKEY_SIZE, CBLSSecretKey>

// line 38
template <typename ImplType, size_t _SerSize, typename C>
class CBLSWrapper
{
    friend class CBLSSecretKey;
    friend class CBLSPublicKey;
    friend class CBLSSignature;

    bool fLegacy;

protected:
    ImplType impl;
    bool fValid{false};
    mutable uint256 cachedHash;
// ...
}

// line 187
inline std::string ToString() const
{
    std::vector<uint8_t> buf = ToByteVector();
    return HexStr(buf.begin(), buf.end());
}
// utilstrencodings.h (dash)
// line 111
template<typename T>
std::string HexStr(const T itbegin, const T itend, bool fSpaces=false)
{
    std::string rv;
    static const char hexmap[16] = { '0', '1', '2', '3', '4', '5', '6', '7',
                                     '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
    rv.reserve((itend-itbegin)*3);
    for(T it = itbegin; it < itend; ++it)
    {
        unsigned char val = (unsigned char)(*it);
        if(fSpaces && it != itbegin)
            rv.push_back(' ');
        rv.push_back(hexmap[val>>4]);
        rv.push_back(hexmap[val&15]);
    }

    return rv;
}
// bls.cpp (dash)
// line 104
CBLSPublicKey CBLSSecretKey::GetPublicKey() const
{
    if (!IsValid()) {
        return CBLSPublicKey();
    }

    CBLSPublicKey pubKey;
    pubKey.impl = impl.GetG1Element(); // CBLSSecretKey::impl is a templated type: bls::PrivateKey
    pubKey.fValid = true;
    pubKey.cachedHash.SetNull();
    return pubKey;
}
// privatekey.cpp (bls-signatures)
// line 103
const G1Element& PrivateKey::GetG1Element() const
{
    if (!fG1CacheValid) {
        CheckKeyData();
        g1_st *p = Util::SecAlloc<g1_st>(1);
        g1_mul_gen(p, keydata);

        g1Cache = G1Element::FromNative(p);
        Util::SecFree(p);
        fG1CacheValid = true;
    }
    return g1Cache;
}
// elements.cpp (bls-signatures)
// line 83
G1Element G1Element::FromNative(const g1_t element)
{
    G1Element ele;
    g1_copy(ele.p, element);
    ele.CheckValid();
    return ele;
}
// relic_bin_util.c (relic)
// line 442
void bn_read_bin(bn_t a, const uint8_t *bin, int len) {
	int i, j;
	dig_t d = (RLC_DIG / 8);
	int digs = (len % d == 0 ? len / d : len / d + 1);

	bn_grow(a, digs);
	bn_zero(a);
	a->used = digs;

	for (i = 0; i < digs - 1; i++) {
		d = 0;
		for (j = (RLC_DIG / 8) - 1; j >= 0; j--) {
			d = d << 8;
			d |= bin[len - 1 - (i * (RLC_DIG / 8) + j)];
		}
		a->dp[i] = d;
	}
	d = 0;
	for (j = (RLC_DIG / 8) - 1; j >= 0; j--) {
		if ((int)(i * (RLC_DIG / 8) + j) < len) {
			d = d << 8;
			d |= bin[len - 1 - (i * (RLC_DIG / 8) + j)];
		}
	}
	a->dp[i] = d;

	a->sign = RLC_POS;
	bn_trim(a);
}
// relic_bn.h (relic)
// line 139
/**
 * Calls a function to allocate and initialize a multiple precision integer.
 *
 * @param[in,out] A			- the multiple precision integer to initialize.
 * @throw ERR_NO_MEMORY		- if there is no available memory.
 */
#if ALLOC == DYNAMIC
#define bn_new(A)															\
	A = (bn_t)calloc(1, sizeof(bn_st));										\
	if ((A) == NULL) {														\
		RLC_THROW(ERR_NO_MEMORY);											\
	}																		\
	bn_make(A, RLC_BN_SIZE);												\

#elif ALLOC == AUTO
#define bn_new(A)															\
	bn_make(A, RLC_BN_SIZE);												\

#endif
// relic_bn_mem.c (relic)
// line 44
void bn_make(bn_t a, int digits) {
	if (digits < 0) {
		RLC_THROW(ERR_NO_VALID);
	}
	/* Allocate at least one digit. */
	digits = RLC_MAX(digits, 1);

#if ALLOC == DYNAMIC
	if (digits % RLC_BN_SIZE != 0) {
		/* Pad the number of digits to a multiple of the block. */
		digits += (RLC_BN_SIZE - digits % RLC_BN_SIZE);
	}

	if (a != NULL) {
		a->dp = NULL;
#if ALIGN == 1
		a->dp = (dig_t *)malloc(digits * sizeof(dig_t));
#elif OPSYS == WINDOWS
		a->dp = _aligned_malloc(digits * sizeof(dig_t), ALIGN);
#else
		int r = posix_memalign((void **)&a->dp, ALIGN, digits * sizeof(dig_t));
		if (r == ENOMEM) {
			RLC_THROW(ERR_NO_MEMORY);
		}
		if (r == EINVAL) {
			RLC_THROW(ERR_NO_VALID);
		}
#endif /* ALIGN */
	}

	if (a->dp == NULL) {
		free((void *)a);
		RLC_THROW(ERR_NO_MEMORY);
	}
#else
	/* Verify if the number of digits is sane. */
	if (digits > RLC_BN_SIZE) {
		RLC_THROW(ERR_NO_PRECI);
		return;
	} else {
		digits = RLC_BN_SIZE;
	}
#endif
	if (a != NULL) {
		a->used = 1;
		a->dp[0] = 0;
		a->alloc = digits;
		a->sign = RLC_POS;
	}
}
// relic_pc.h (relic)
// line 224
/**
 * Old macros to preserve interface.
 * @{
 */
#define g1_get_ord			pc_get_ord

// line 217
/**
 * Returns the order of the groups G_1, G_2 and G_T.
 *
 * @param[out] N			0 the returned order.
 */
#define pc_get_ord(N)		RLC_CAT(RLC_G1_LOWER, curve_get_ord)(N)

// line 58
#define RLC_G1_LOWER			ep_
#define RLC_G1_UPPER			EP

// relic_util.h
// 154
/**
 * Concatenates two tokens.
 */
/** @{ */
#define RLC_CAT(A, B)			_RLC_CAT(A, B)
#define _RLC_CAT(A, B)			A ## B

// relic_ep_curve.c
// line 358
void ep_curve_get_ord(bn_t n) {
	bn_copy(n, &core_get()->ep_r);
}

// relic_bn_util.c
// line 49
void bn_copy(bn_t c, const bn_t a) {
	if (c->dp == a->dp) {
		return;
	}

	bn_grow(c, a->used);
	dv_copy(c->dp, a->dp, a->used);

	c->used = a->used;
	c->sign = a->sign;
	bn_trim(c);
}

// relic_core.c
// line 197
ctx_t *core_get(void) {
#if defined(MULTI)
    if (core_ctx == NULL && core_thread_initializer != NULL) {
        core_thread_initializer(core_init_ptr);
    }
#endif
	return core_ctx;
}

// line 96
#if MULTI
rlc_thread ctx_t *core_ctx = NULL;
#else
static ctx_t *core_ctx = NULL;
#endif

// relic_core.h
// line 135
typedef struct _ctx_t {
	/** The value returned by the last call, can be RLC_OK or RLC_ERR. */
	int code;

#ifdef CHECK
	/** The state of the last error caught. */
	sts_t *last;
	/** Error state to be used outside try-catch blocks. */
	sts_t error;
	/** Error number to be used outside try-catch blocks. */
	err_t number;
	/** The error message respective to the last error. */
	char *reason[ERR_MAX];
	/** A flag to indicate if the last error was already caught. */
	int caught;
#endif /* CHECK */

#ifdef WITH_FB
	/** Identifier of the currently configured binary field. */
	int fb_id;
	/** Irreducible binary polynomial. */
	fb_st fb_poly;
	/** Non-zero coefficients of a trinomial or pentanomial. */
	int fb_pa, fb_pb, fb_pc;
	/** Positions of the non-zero coefficients of trinomials or pentanomials. */
	int fb_na, fb_nb, fb_nc;
#if FB_TRC == QUICK || !defined(STRIP)
	/** Powers of z with non-zero traces. */
	int fb_ta, fb_tb, fb_tc;
#endif /* FB_TRC == QUICK */
#if FB_SLV == QUICK || !defined(STRIP)
	/** Table of precomputed half-traces. */
	fb_st fb_half[(RLC_DIG / 8 + 1) * RLC_FB_DIGS][16];
#endif /* FB_SLV == QUICK */
#if FB_SRT == QUICK || !defined(STRIP)
	/** Square root of z. */
	fb_st fb_srz;
#ifdef FB_PRECO
	/** Multiplication table for the polynomial z^(1/2). */
	fb_st fb_tab_srz[256];
#endif /* FB_PRECO */
#endif /* FB_SRT == QUICK */
#if FB_INV == ITOHT || !defined(STRIP)
	/** Stores an addition chain for (RLC_FB_BITS - 1). */
	int chain[RLC_TERMS + 1];
	/** Stores the length of the addition chain. */
	int chain_len;
	/** Tables for repeated squarings. */
	fb_st fb_tab_sqr[RLC_TERMS][RLC_FB_TABLE];
#endif /* FB_INV == ITOHT */
#endif /* WITH_FB */

#ifdef WITH_EB
	/** Identifier of the currently configured binary elliptic curve. */
	int eb_id;
	/** The a-coefficient of the elliptic curve. */
	fb_st eb_a;
	/** The b-coefficient of the elliptic curve. */
	fb_st eb_b;
	/** Optimization identifier for the a-coefficient. */
	int eb_opt_a;
	/** Optimization identifier for the b-coefficient. */
	int eb_opt_b;
	/** The generator of the elliptic curve. */
	eb_st eb_g;
	/** The order of the group of points in the elliptic curve. */
	bn_st eb_r;
	/** The cofactor of the group order in the elliptic curve. */
	bn_st eb_h;
	/** Flag that stores if the binary curve has efficient endomorphisms. */
	int eb_is_kbltz;
#ifdef EB_PRECO
	/** Precomputation table for generator multiplication. */
	eb_st eb_pre[RLC_EB_TABLE];
	/** Array of pointers to the precomputation table. */
	eb_st *eb_ptr[RLC_EB_TABLE];
#endif /* EB_PRECO */
#endif /* WITH_EB */

#ifdef WITH_FP
	/** Identifier of the currently configured prime field. */
	int fp_id;
	/** Prime modulus. */
	bn_st prime;
	/** Parameter for generating prime. */
	bn_st par;
	/** Parameter in sparse form. */
	int par_sps[RLC_TERMS + 1];
	/** Length of sparse prime representation. */
	int par_len;
#if FP_RDC == MONTY || !defined(STRIP)
	/** Value (R^2 mod p) for converting small integers to Montgomery form. */
	bn_st conv;
	/** Value of constant one in Montgomery form. */
	bn_st one;
#endif /* FP_RDC == MONTY */
#if FP_INV == JUMPDS || !defined(STRIP)
	/** Value of constant for divstep-based inversion. */
	bn_st inv;
#endif /* FP_INV */
	/** Prime modulus modulo 8. */
	dig_t mod8;
	/** Value derived from the prime used for modular reduction. */
	dig_t u;
	/** Quadratic non-residue. */
	int qnr;
	/** Cubic non-residue. */
	int cnr;
	/** 2-adicity. */
	int ad2;
#if FP_RDC == QUICK || !defined(STRIP)
	/** Sparse representation of prime modulus. */
	int sps[RLC_TERMS + 1];
	/** Length of sparse prime representation. */
	int sps_len;
#endif /* FP_RDC == QUICK */
#endif /* WITH_FP */

#ifdef WITH_EP
	/** Identifier of the currently configured prime elliptic curve. */
	int ep_id;
	/** The a-coefficient of the elliptic curve. */
	fp_st ep_a;
	/** The b-coefficient of the elliptic curve. */
	fp_st ep_b;
	/** The value 3b used in elliptic curve arithmetic. */
	fp_st ep_b3;
	/** The generator of the elliptic curve. */
	ep_st ep_g;
	/** The order of the group of points in the elliptic curve. */
	bn_st ep_r;
	/** The cofactor of the group order in the elliptic curve. */
	bn_st ep_h;
	/** The distinguished non-square used by the mapping function */
	fp_st ep_map_u;
	/** Precomputed constants for hashing. */
	fp_st ep_map_c[4];
#ifdef EP_ENDOM
#if EP_MUL == LWNAF || EP_FIX == COMBS || EP_FIX == LWNAF || EP_SIM == INTER || !defined(STRIP)
	/** Parameters required by the GLV method. @{ */
	fp_st beta;
	bn_st ep_v1[3];
	bn_st ep_v2[3];
	/** @} */
#endif /* EP_MUL */
#endif /* EP_ENDOM */
	/** Optimization identifier for the a-coefficient. */
	int ep_opt_a;
	/** Optimization identifier for the b-coefficient. */
	int ep_opt_b;
	/** Optimization identifier for the b3 value. */
	int ep_opt_b3;
	/** Flag that stores if the prime curve has efficient endomorphisms. */
	int ep_is_endom;
	/** Flag that stores if the prime curve is supersingular. */
	int ep_is_super;
	/** Flag that stores if the prime curve is pairing-friendly. */
	int ep_is_pairf;
	/** Flag that indicates whether this curve uses an isogeny for the SSWU mapping. */
	int ep_is_ctmap;
#ifdef EP_PRECO
	/** Precomputation table for generator multiplication. */
	ep_st ep_pre[RLC_EP_TABLE];
	/** Array of pointers to the precomputation table. */
	ep_st *ep_ptr[RLC_EP_TABLE];
#endif /* EP_PRECO */
#ifdef EP_CTMAP
	/** The isogeny map coefficients for the SSWU mapping. */
	iso_st ep_iso;
#endif /* EP_CTMAP */
#endif /* WITH_EP */

#ifdef WITH_EPX
	/** The generator of the elliptic curve. */
	ep2_t ep2_g;
	/** The 'a' coefficient of the curve. */
	fp2_t ep2_a;
	/** The 'b' coefficient of the curve. */
	fp2_t ep2_b;
	/** The order of the group of points in the elliptic curve. */
	bn_st ep2_r;
	/** The cofactor of the group order in the elliptic curve. */
	bn_st ep2_h;
	/** The distinguished non-square used by the mapping function */
	fp2_t ep2_map_u;
	/** The constants needed for hashing. */
	fp2_t ep2_map_c[4];
	/** The constants needed for Frobenius. */
	fp2_t ep2_frb[2];
	/** Optimization identifier for the a-coefficient. */
	int ep2_opt_a;
	/** Optimization identifier for the b-coefficient. */
	int ep2_opt_b;
	/** Flag that stores if the prime curve is a twist. */
	int ep2_is_twist;
	/** Flag that indicates whether this curve uses an isogeny for the SSWU mapping. */
	int ep2_is_ctmap;
#ifdef EP_PRECO
	/** Precomputation table for generator multiplication.*/
	ep2_st ep2_pre[RLC_EP_TABLE];
	/** Array of pointers to the precomputation table. */
	ep2_st *ep2_ptr[RLC_EP_TABLE];
#endif /* EP_PRECO */
#ifdef EP_CTMAP
	/** The isogeny map coefficients for the SSWU mapping. */
	iso2_st ep2_iso;
#endif /* EP_CTMAP */
	/** The generator of the elliptic curve. */
	ep4_t ep4_g;
	/** The 'a' coefficient of the curve. */
	fp4_t ep4_a;
	/** The 'b' coefficient of the curve. */
	fp4_t ep4_b;
	/** The order of the group of points in the elliptic curve. */
	bn_st ep4_r;
	/** The cofactor of the group order in the elliptic curve. */
	bn_st ep4_h;
	/** Optimization identifier for the a-coefficient. */
	int ep4_opt_a;
	/** Optimization identifier for the b-coefficient. */
	int ep4_opt_b;
	/** Flag that stores if the prime curve is a twist. */
	int ep4_is_twist;
#ifdef EP_PRECO
	/** Precomputation table for generator multiplication.*/
	ep4_st ep4_pre[RLC_EP_TABLE];
	/** Array of pointers to the precomputation table. */
	ep4_st *ep4_ptr[RLC_EP_TABLE];
	#endif /* EP_PRECO */
#endif /* WITH_EPX */

#ifdef WITH_ED
	/** Identifier of the currently configured Edwards elliptic curve. */
	int ed_id;
	/** The 'a' coefficient of the Edwards elliptic curve. */
	fp_st ed_a;
	/** The 'd' coefficient of the Edwards elliptic curve. */
	fp_st ed_d;
	/** Precomputed constants for hashing. */
	fp_st ed_map_c[4];
	/** The generator of the Edwards elliptic curve. */
	ed_st ed_g;
	/** The order of the group of points in the Edwards elliptic curve. */
	bn_st ed_r;
	/** The cofactor of the Edwards elliptic curve. */
	bn_st ed_h;

#ifdef ED_PRECO
	/** Precomputation table for generator multiplication. */
	ed_st ed_pre[RLC_ED_TABLE];
	/** Array of pointers to the precomputation table. */
	ed_st *ed_ptr[RLC_ED_TABLE];
#endif /* ED_PRECO */
#endif

#if defined(WITH_FPX) || defined(WITH_PP)
	/** Integer part of the quadratic non-residue. */
	dis_t qnr2;
	/** Constants for computing Frobenius maps in higher extensions. @{ */
	fp2_st fp2_p1[5];
	fp2_st fp2_p2[3];
	fp2_st fp4_p1;
	/** @} */
	/** Constants for computing Frobenius maps in higher extensions. @{ */
	int frb3[3];
	fp_st fp3_p0[2];
	fp_st fp3_p1[5];
	fp_st fp3_p2[2];
	/** @} */
#endif /* WITH_PP */

#if defined(WITH_PC)
	gt_t gt_g;
#endif

#if BENCH > 0
	/** Stores the time measured before the execution of the benchmark. */
	ben_t before;
	/** Stores the time measured after the execution of the benchmark. */
	ben_t after;
	/** Stores the sum of timings for the current benchmark. */
	long long total;
#ifdef OVERH
	/** Benchmarking overhead to be measured and subtracted from benchmarks. */
	long long over;
#endif
#endif

#if RAND != CALL
	/** Internal state of the PRNG. */
	uint8_t rand[RLC_RAND_SIZE];
#else
	void (*rand_call)(uint8_t *, int, void *);
	void *rand_args;
#endif
	/** Flag to indicate if PRNG is seed. */
	int seeded;
	/** Counter to keep track of number of calls since last seeding. */
	int counter;

#if TIMER == PERF
	/** File descriptor for perf system call. */
	int perf_fd;
	/** Buffer for storing perf data, */
	struct perf_event_mmap_page *perf_buf;
#endif
} ctx_t;

rename `--static-seed` and provide option to accept a seed secret

I think what we're calling seed has already been named secret. If that's the case, we should probably stick to the existing nomenclature.

  • create an option --seed <seed> which accepts a specific seed (probably as hex?)
    • perhaps this should be a subcommand fromsecret for compatibility? or use the flag --from-secret for recognition?
  • rename --static-seed to --from-example-secret and show the seed secret in the output?
  • --gen-dash-from-secret seems redundant - a matter of documentation, not implementation

I'm really torn on the fromsecret thing... that doesn't make since to have the input be "secret" and the output also be "secret. Perhaps an alias would be best:

fromsecret, --from-secret       : alias of `--seed`, for compatibility with `dash-cli`

v1 Feedback: Release and CLI options

Should not have multiple macOS subversion releases

macOS 11 binaries will work on macOS 12+

Unless an app is using new APIs that are only available in a new version of macOS - such as the new AI neural compute stuff or FaceTime Stage, etc - macOS is just macOS.

There are exceptions to that rule and it's good to have the documentation and scripts available for creating different versions on different releases, but macOS 11 is a good enough build target for macOS 12 and macOS 13 in almost all cases.

subcommand or flag to generate a valid seed

Needed Documentation

Are all random bytes of the necessary bitlength valid seeds?

What are the min and max widths?

Can a seed be used to generate multiple keys? Do we need an index option to generate the nth key?

bls -n 3
[
  { ... }, { ... }, { ... }
]

```sh
bls -i 5 -n 3 --seed <my-hex-seed>
[
  { ... }, { ... }, { ... }
]

Corresponding CLI capabilities

Maybe bls --generate-seed to generate a valid seed within the specified parameters?

v1 Feedback: README

Move the deep explanations to an issue or in ./docs and keep the README very clean.

Here's are a few examples:

Updates:

  • One line description "generates BLS keypair, based on [Relic vX.Y](link) and [BLS-Signatures](link) vX.Y"
  • Example usage & output bls gen --json
  • How to install via webi
  • How to install from GitHub Releases (curl, chmod, xattr)
  • How to build from source on Linux, something like this
    sudo apt install -y build-essential ...
    git clone https://github.com/dashhive/bls
    cd ./bls/
    cp example.config.ext config.ext
    sh ./install.sh
  • (maybe?) How to use the underlying library

clarification of terms

Seed

1. Structure

Is every random 256-bit (32-byte, 64-character) hex string a valid seed, or does it have some constraints?

In other words:

If I run openssl rand -hex 32 a million billion trillion times, will all outputs always be valid seeds?

2. Usage

Do we know anything about the mechanism that turns a seed into a secret?

For example: is it based on a typical CSPRNG? Or a curve? Or something else?

Secret

1. Structure

Is every random 32-byte array a valid secret? Or are there some constraints?

IIRC, the code just iterates through 32-byte CSPRNG buffers until it finds one that doesn't fail to generate a public key.

version output

The version output has an extra . at the beginning

bls --version
v.2.0.0

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.