mirror of
https://github.com/fluencelabs/js-libp2p-crypto
synced 2025-03-15 15:21:07 +00:00
feat(keys): implement generateKeyPairFromSeed for ed25519
Implement generateKeyPairFromSeed for ed25519 - this will produce the same keypair for the same seed (or first 32 bytes of reader) as given to GenerateKeyPairWithReader in go-libp2p.
This commit is contained in:
parent
20326199d9
commit
e5b7c1f622
@ -22,6 +22,22 @@ exports.generateKey = function (callback) {
|
||||
done(null, keys)
|
||||
}
|
||||
|
||||
// seed should be a 32 byte uint8array
|
||||
exports.generateKeyFromSeed = function (seed, callback) {
|
||||
const done = (err, res) => setImmediate(() => {
|
||||
callback(err, res)
|
||||
})
|
||||
|
||||
let keys
|
||||
try {
|
||||
keys = nacl.sign.keyPair.fromSeed(seed)
|
||||
} catch (err) {
|
||||
done(err)
|
||||
return
|
||||
}
|
||||
done(null, keys)
|
||||
}
|
||||
|
||||
exports.hashAndSign = function (key, msg, callback) {
|
||||
setImmediate(() => {
|
||||
callback(null, Buffer.from(nacl.sign.detached(msg, key)))
|
||||
|
13
src/index.js
13
src/index.js
@ -30,6 +30,19 @@ exports.generateKeyPair = (type, bits, cb) => {
|
||||
key.generateKeyPair(bits, cb)
|
||||
}
|
||||
|
||||
// Generates a keypair of the given type and bitsize
|
||||
// seed is a 32 byte uint8array
|
||||
exports.generateKeyPairFromSeed = (type, seed, bits, cb) => {
|
||||
let key = keys[type.toLowerCase()]
|
||||
if (!key) {
|
||||
return cb(new Error('invalid or unsupported key type'))
|
||||
}
|
||||
if (type.toLowerCase() !== 'ed25519') {
|
||||
return cb(new Error('Seed key derivation is unimplemented for RSA or secp256k1'))
|
||||
}
|
||||
key.generateKeyPairFromSeed(seed, bits, cb)
|
||||
}
|
||||
|
||||
// Converts a protobuf serialized public key into its
|
||||
// representative object
|
||||
exports.unmarshalPublicKey = (buf) => {
|
||||
|
@ -117,6 +117,27 @@ function generateKeyPair (_bits, cb) {
|
||||
})
|
||||
}
|
||||
|
||||
function generateKeyPairFromSeed (seed, _bits, cb) {
|
||||
if (cb === undefined && typeof _bits === 'function') {
|
||||
cb = _bits
|
||||
}
|
||||
|
||||
crypto.generateKeyFromSeed(seed, (err, keys) => {
|
||||
if (err) {
|
||||
return cb(err)
|
||||
}
|
||||
let privkey
|
||||
try {
|
||||
privkey = new Ed25519PrivateKey(keys.secretKey, keys.publicKey)
|
||||
} catch (err) {
|
||||
cb(err)
|
||||
return
|
||||
}
|
||||
|
||||
cb(null, privkey)
|
||||
})
|
||||
}
|
||||
|
||||
function ensure (cb) {
|
||||
if (typeof cb !== 'function') {
|
||||
throw new Error('callback is required')
|
||||
@ -138,5 +159,6 @@ module.exports = {
|
||||
Ed25519PrivateKey,
|
||||
unmarshalEd25519PrivateKey,
|
||||
unmarshalEd25519PublicKey,
|
||||
generateKeyPair
|
||||
generateKeyPair,
|
||||
generateKeyPairFromSeed
|
||||
}
|
||||
|
@ -35,6 +35,70 @@ describe('ed25519', () => {
|
||||
})
|
||||
})
|
||||
|
||||
it('generates a valid key from seed', (done) => {
|
||||
var seed = crypto.randomBytes(32)
|
||||
crypto.generateKeyPairFromSeed('Ed25519', seed, 512, (err, seededkey) => {
|
||||
if (err) return done(err)
|
||||
expect(
|
||||
seededkey
|
||||
).to.be.an.instanceof(
|
||||
ed25519.Ed25519PrivateKey
|
||||
)
|
||||
|
||||
seededkey.hash((err, digest) => {
|
||||
if (err) {
|
||||
return done(err)
|
||||
}
|
||||
|
||||
expect(digest).to.have.length(34)
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('generates the same key from the same seed', (done) => {
|
||||
var seed = crypto.randomBytes(32)
|
||||
crypto.generateKeyPairFromSeed('Ed25519', seed, 512, (err, seededkey1) => {
|
||||
if (err) return done(err)
|
||||
crypto.generateKeyPairFromSeed('Ed25519', seed, 512, (err, seededkey2) => {
|
||||
if (err) return done(err)
|
||||
expect(
|
||||
seededkey1.equals(seededkey2)
|
||||
).to.be.eql(
|
||||
true
|
||||
)
|
||||
expect(
|
||||
seededkey1.public.equals(seededkey2.public)
|
||||
).to.be.eql(
|
||||
true
|
||||
)
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('generates different keys for different seeds', (done) => {
|
||||
var seed1 = crypto.randomBytes(32)
|
||||
crypto.generateKeyPairFromSeed('Ed25519', seed1, 512, (err, seededkey1) => {
|
||||
if (err) return done(err)
|
||||
var seed2 = crypto.randomBytes(32)
|
||||
crypto.generateKeyPairFromSeed('Ed25519', seed2, 512, (err, seededkey2) => {
|
||||
if (err) return done(err)
|
||||
expect(
|
||||
seededkey1.equals(seededkey2)
|
||||
).to.be.eql(
|
||||
false
|
||||
)
|
||||
expect(
|
||||
seededkey1.public.equals(seededkey2.public)
|
||||
).to.be.eql(
|
||||
false
|
||||
)
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('signs', (done) => {
|
||||
const text = crypto.randomBytes(512)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user