Skip to content

Commit c599027

Browse files
feat: added back in private keys from BIP32 Seed (dashpay#29)
* feat: added back in private keys from BIP32 Seed * feat: added in unit test
1 parent 7a690fd commit c599027

File tree

3 files changed

+39
-0
lines changed

3 files changed

+39
-0
lines changed

src/privatekey.cpp

+29
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,35 @@ namespace bls {
1919

2020
const size_t PrivateKey::PRIVATE_KEY_SIZE;
2121

22+
PrivateKey PrivateKey::FromSeedBIP32(const Bytes& seed) {
23+
// "BLS private key seed" in ascii
24+
const uint8_t hmacKey[] = {66, 76, 83, 32, 112, 114, 105, 118, 97, 116, 101,
25+
32, 107, 101, 121, 32, 115, 101, 101, 100};
26+
27+
auto* hash = Util::SecAlloc<uint8_t>(
28+
PrivateKey::PRIVATE_KEY_SIZE);
29+
30+
// Hash the seed into sk
31+
md_hmac(hash, seed.begin(), (int)seed.size(), hmacKey, sizeof(hmacKey));
32+
33+
bn_t order;
34+
bn_new(order);
35+
g1_get_ord(order);
36+
37+
// Make sure private key is less than the curve order
38+
bn_t* skBn = Util::SecAlloc<bn_t>(1);
39+
bn_new(*skBn);
40+
bn_read_bin(*skBn, hash, PrivateKey::PRIVATE_KEY_SIZE);
41+
bn_mod_basic(*skBn, *skBn, order);
42+
43+
PrivateKey k;
44+
bn_copy(k.keydata, *skBn);
45+
46+
Util::SecFree(skBn);
47+
Util::SecFree(hash);
48+
return k;
49+
}
50+
2251
// Construct a private key from a bytearray.
2352
PrivateKey PrivateKey::FromBytes(const Bytes& bytes, bool modOrder)
2453
{

src/privatekey.hpp

+3
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ class PrivateKey {
3131
// less than the group order (which is in bls.hpp).
3232
static const size_t PRIVATE_KEY_SIZE = 32;
3333

34+
// Construct a private key from a BIP32 based seed.
35+
static PrivateKey FromSeedBIP32(const Bytes& seed);
36+
3437
// Construct a private key from a bytearray.
3538
static PrivateKey FromBytes(const Bytes& bytes, bool modOrder = false);
3639

src/test.cpp

+7
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,13 @@ TEST_CASE("class PrivateKey") {
121121
REQUIRE_THROWS(PrivateKey::FromBytes(Bytes(buffer, PrivateKey::PRIVATE_KEY_SIZE), false));
122122
REQUIRE_NOTHROW(PrivateKey::FromBytes(Bytes(buffer, PrivateKey::PRIVATE_KEY_SIZE), true));
123123
}
124+
SECTION("BIP32 Seed") {
125+
uint8_t aliceSeed[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
126+
PrivateKey pk1 = PrivateKey::FromSeedBIP32(Bytes(aliceSeed, 10));
127+
vector<uint8_t> privateKey = pk1.Serialize(true);
128+
vector<uint8_t> knownPrivateKey = Util::HexToBytes("46891c2cec49593c81921e473db7480029e0fc1eb933c6b93d81f5370eb19fbd");
129+
REQUIRE(privateKey == knownPrivateKey);
130+
}
124131
SECTION("keydata checks") {
125132
PrivateKey pk1 = PrivateKey::FromByteVector(getRandomSeed(), true);
126133
G1Element g1 = pk1.GetG1Element();

0 commit comments

Comments
 (0)